类型系统
基本类型
boolean 类型
boolean
类型只包含 true
和 false
两个布尔值。
string 类型
string
类型包含所有字符串。
number 类型
number
类型包含所有整数和浮点数。
bigint 类型
bigint
类型包含所有的大整数。
bigint
与 number
类型不兼容。
symbol 类型
symbol
类型包含所有的 Symbol
值。
object 类型
object
类型包含了所有对象、数组和函数。
undefined 类型,null 类型
undefined
和 null
是两种独立类型,它们各自都只有一个值。
如果没有声明类型的变量被赋值为 undefined
或 null
,它们的类型会被推断为 any
。
包装对象类型
- Boolean 和 boolean
- String 和 string
- Number 和 number
- BigInt 和 bigint
- Symbol 和 symbol
大写类型同时包含包装对象和字面量两种情况,小写类型只包含字面量,不包含包装对象。
建议只使用小写类型。
const s1: String = new String("s1");
const s2: String = "s2";
// const s3: string = new String("s3"); // 报错
const s4: string = "s4";
Object 类型与 object 类型
都只包含 JavaScript 内置对象原生的属性和方法,不包含用户自定义的属性和方法。
Object 类型
所有可以转成对象的值(原始类型值、对象、数组、函数),都是合法的 Object
类型。
除了 undefined
和 null
这两个值不能转为对象,其他任何值都可以赋值给 Object
类型。
空对象{}
是 Object
类型的简写形式,所以使用 Object
时常常用空对象代替。
object 类型
object
类型代表可以用字面量表示的对象,只包含对象、数组和函数。
建议总是使用小写类型 object
。
undefined 和 null 的特殊性
undefined
和 null
既是值,又是类型。
作为值,任何其他类型的变量都可以赋值为 undefined
或 null
。
值类型
TypeScript 规定,单个值也是一种类型,称为“值类型”。
TypeScript 推断类型时,遇到 const
命令声明的非对象变量,如果代码里面没有注明类型,就会推断该变量是值类型。
// x 的类型是 "https"
const x = "https";
// y 的类型是 string
const y: string = "https";
// x 的类型是 { foo: number }
const x = { foo: 1 };
联合类型
联合类型(union types
)指的是多个类型组成的一个新类型,使用符号|
表示。
联合类型 A|B
表示,任何一个类型只要属于 A
或 B
,就属于联合类型 A|B
。
联合类型的第一个成员前面,也可以加上竖杠|
,这样便于多行书写。
如果一个变量有多种类型,读取该变量时,往往需要进行“类型缩小”(type narrowing
),区分该值到底属于哪一种类型,然后再进一步处理。
交叉类型
交叉类型(intersection types
)指的多个类型组成的一个新类型,使用符号&表示。
交叉类型 A&B
表示,任何一个类型必须同时属于 A
和 B
,才属于交叉类型 A&B
,即交叉类型同时满足 A
和 B
的特征。
交叉类型的主要用途是表示对象的合成。
let obj: { foo: string } & { bar: string };
obj = {
foo: "hello",
bar: "world",
};
交叉类型常常用来为对象类型添加新属性。
type A = { foo: number };
type B = A & { bar: number };
type 命令
type
命令用来定义一个类型的别名。
别名不允许重名。
别名的作用域是块级作用域。这意味着,代码块内部定义的别名,影响不到外部。
type Color = "red";
if (Math.random() < 0.5) {
type Color = "blue";
}
别名支持使用表达式,也可以在定义一个别名时,使用另一个别名,即别名允许嵌套。
type World = "world";
type Greeting = `hello ${World}`;
typeof 运算符
Javascript 中,typeof
返回值的类型,只可能返回 8 种结果,都是字符串。
typeof undefined; // "undefined"
typeof true; // "boolean"
typeof 1337; // "number"
typeof "foo"; // "string"
typeof {}; // "object"
typeof parseInt; // "function"
typeof Symbol(); // "symbol"
typeof 127n; // "bigint"
Typescript 中,typeof
依旧返回值的类型,但返回的是值的 TypeScript 类型,不是字符串,只能用在类型运算之中。
const a = { x: 0 };
type T0 = typeof a; // { x: number }
type T1 = typeof a.x; // number
重要区别是,编译后,Javascript 中获取值类型的代码会保留,Typescript 中获取值类型的代码会被替换。
块级类型声明
TypeScript 支持块级类型声明,即类型可以声明在代码块(用大括号表示)里面,并且只在当前代码块有效。
类型的兼容
TypeScript 的一个规则是,凡是可以使用父类型的地方,都可以使用子类型,但是反过来不行。
因为子类型继承了父类型的所有特征,所以可以用在父类型的场合。但是,子类型还可能有一些父类型没有的特征,所以父类型不能用在子类型的场合。