基础类型
-Type string trivially inferred from a string literal, remove type annotation (no-inferrable-types) 如1. tslint觉得自己根据右边的false判断出Type的类型是boolean,所以,认为再写boolean是多此一举。
“@typescript-eslint/no-inferrable-types”: “off” 针对string boolean Number
1 Boolean 类型
let Type: boolean = false
2 Number 类型
let count: number = 10;
3 String 类型
let name: string = "TypeScript";
4 Symbol 类型
const Type = Symbol('Type')
const obj = {
[Type]: 'liao',
age: 18,
}
const SymbolPropNames = Object.getOwnPropertySymbols(obj);
console.log(SymbolPropNames);
// [ Symbol(Type) ]
console.log(obj[SymbolPropNames[0]]);
// 'liao'
5 Array 类型
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3]; // Array<number>泛型语法
let list: any[] = [1, '1', []];
6 Enum 类型 TypeScript 支持数字和字符串的枚举。
6.1数字枚举
//d1
enum Direction {
NORTH,
SOUTH,
EAST,
WEST,
}
const dir: Direction = Direction.NORTH
const dir2= Direction[1] // SOUTH
//d2
enum Direction {
NORTH = 3,
SOUTH,
EAST,
WEST,
}
const dir: Direction = Direction.NORTH
const dir2= Direction
console.log(dir, dir2)
// 3 {
// '3': 'NORTH',
// '4': 'SOUTH',
// '5': 'EAST',
// '6': 'WEST',
// NORTH: 3,
// SOUTH: 4,
// EAST: 5,
// WEST: 6
// }
默认情况下,NORTH 的初始值为 0,其余的成员会从 1 开始自动增长。换句话说,Direction.SOUTH 的值为 1,Direction.EAST 的值为 2,Direction.WEST 的值为 3。
当然我们也可以设置 NORTH 的初始值,比如d2
6.2字符串枚举
在 TypeScript 2.4 版本,允许我们使用字符串枚举。在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum Direction {
NORTH = "NORTH",
SOUTH = "SOUTH",
EAST = "EAST",
WEST = "WEST",
}
//NORTH { NORTH: 'NORTH', SOUTH: 'SOUTH', EAST: 'EAST', WEST: 'WEST' }
6.3常量枚举
除了数字枚举和字符串枚举之外,还有一种特殊的枚举 —— 常量枚举。它是使用 const 关键字修饰的枚举,常量枚举会使用内联语法,不会为枚举类型编译生成任何 JavaScript。为了更好地理解这句话,我们来看一个具体的例子:
const enum Direction {
NORTH,
SOUTH,
EAST,
WEST,
}
console.log(Direction.NORTH) //0
console.log(Direction) //'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.
6.4异构枚举
异构枚举的成员值是数字和字符串的混合:
enum Enum {
A,
B,
C = "C",
D = "D",
E = 8,
F,
}
console.log(Enum.A) //输出:0
console.log(Enum[0]) // 输出:A
7 Any 类型
在 TypeScript 中,任何类型都可以被归为 any 类型。这让 any 类型成为了类型系统的顶级类型(也被称作全局超级类型)。
let super: any = 666;
super = "1111";
super = false;
let value: any;
value.foo.bar; // OK
value.trim(); // OK
value(); // OK
new value(); // OK
value[0][1]; // OK
在许多场景下,这太宽松了。使用 any 类型,可以很容易地编写类型正确但在运行时有问题的代码。如果我们使用 any 类型,就无法使用 TypeScript 提供的大量的保护机制。
为了解决 any 带来的问题,TypeScript 3.0 引入了 unknown 类型
8 Unknown 类型
就像所有类型都可以赋值给 any,所有类型也都可以赋值给 unknown。这使得 unknown 成为 TypeScript 类型系统的另一种顶级类型(另一种是 any)。
但是unknown 类型只能被赋值给 any 类型和 unknown 类型本身。直观地说,这是有道理的:只有能够保存任意类型值的容器才能保存 unknown 类型的值。毕竟我们不知道变量 value 中存储了什么类型的值。
let value: unknown;
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK
value = true; // OK
const value1: unknown = value; // OK
const value2: any = value; // OK
const value3: boolean = value; // Error
const value4: number = value; // Error
const value5: string = value; // Error
const value6: object = value; // Error
const value7: any[] = value; // Error
const value8: Function = value; // Error
function abc(value:boolean) {
return value
}
abc(value)// Error
9 Tuple 类型
众所周知,数组一般由同种类型的值组成,但有时我们需要在单个变量中存储不同类型的值,这时候我们就可以使用元组。在 JavaScript 中是没有元组的,元组是 TypeScript 中特有的类型,其工作方式类似于数组。
元组可用于定义具有有限数量的未命名属性的类型。每个属性都有一个关联的类型。使用元组时,必须提供每个属性的值。
let tupleType: [string, boolean] = ['tupleType', true]
10 Void类型
Void 类型
某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。当一个函数没有返回值时,你通常会见到其返回值类型是 void:
// 声明函数返回值为void
function warnUser(): void {
console.log("This is my warning message");
}
//经常用的类型声明 ()=> Void
//需要注意的是,声明一个 void 类型的变量没有什么作用,因为它的值只能为 undefined 或 null:
let unusable: void = undefined;
11 Null 和 Undefined 类型
TypeScript 里,undefined 和 null 两者有各自的类型分别为 undefined 和 null。
let u: undefined = undefined;
let n: null = null;
默认情况下 null 和 undefined 是所有类型的子类型。 就是说你可以把 null 和 undefined 赋值给 number 类型的变量。
12 object, Object 和 {} 类型
12.1 object 类型
//表示⾮原始类型。object是键值对集合,特殊在值也必须是object。
// 注意:object类型默认可以使用在 Object 类型上定义的所有属性和方法,这些属性和方法可通过 JavaScript 的原型链隐式地使用,但是如果在object中重写了原型链中的属性或者方法,那么会直接覆盖,不受原型链上的影响!
let obj: object;
obj = 1; // Error:Type 'number' is not assignable to type 'object'.
obj = true; // Error: Type 'boolean' is not assignable to type 'object'.
obj = 'a'; // Error: Type 'string' is not assignable to type 'object'.
obj = undefined; //Error:Type 'undefined' is not assignable to type 'object'.
obj = {
a : "hell oworld",
b : 1,
c : true,
}
obj = {
toString() {
return 123;
}
}
console.log(obj.toString()) // 123
12.2 Object 类型
//源码
interface Object {
/** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
constructor: Function;
/** Returns a string representation of an object. */
toString(): string;
/** Returns a date converted to a string using the current locale. */
toLocaleString(): string;
/** Returns the primitive value of the specified object. */
valueOf(): Object;
/**
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: PropertyKey): boolean;
/**
* Determines whether an object exists in another object's prototype chain.
* @param v Another object whose prototype chain is to be checked.
*/
isPrototypeOf(v: Object): boolean;
/**
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: PropertyKey): boolean;
}
//涉及原型链部分不说了 Object类型包含了所有的原始/基础类型,所以可以给Object类型赋值为基础类型;如果值对象属性名与 Object 接口中的属性冲突,则 TypeScript 编译器会提示相应的错误:如下例,对象中重写了toString方法,但是返回类型和Object中返回类型string冲突,所以报错;
let obj: Object // 或者 let obj = new Object();
obj = 'hell oworld'
obj = 1
obj = true
obj={}
obj = undefined //Error:Type 'undefined' is not assignable to type 'Object'.
12.3 {} 类型
{} 类型描述了一个没有成员的对象。当你试图访问这样一个对象的任意属性时,TypeScript 会产生一个编译时错误。
// Type {}
const obj = {};
// Error: Property 'prop' does not exist on type '{}'.
obj.prop = "semlinker";
但是,你仍然可以使用在 Object 类型上定义的所有属性和方法,这些属性和方法可通过 JavaScript 的原型链隐式地使用:
// Type {}
const obj = {};
// "[object Object]"
obj.toString();
13 Never 类型
never 类型表示的是那些永不存在的值的类型。 例如,never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。
// 返回never的函数必须存在无法达到的终点 注意这个else 就是针对foo 实参传递非type Foo类型的值是 触发的分支
function error(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
type Foo = string | number;
function controlFlowAnalysisWithNever(foo: Foo) {
if (typeof foo === "string") {
// 这里 foo 被收窄为 string 类型
} else if (typeof foo === "number") {
// 这里 foo 被收窄为 number 类型
} else {
// foo 在这里是 never
const check: never = foo;
}
}