【阮一峰】1.类型系统

发布于:2025-02-20 ⋅ 阅读:(102) ⋅ 点赞:(0)

类型系统

基本类型

boolean 类型

boolean 类型只包含 truefalse 两个布尔值。

string 类型

string 类型包含所有字符串。

number 类型

number 类型包含所有整数和浮点数。

bigint 类型

bigint 类型包含所有的大整数。

bigintnumber 类型不兼容。

symbol 类型

symbol 类型包含所有的 Symbol 值。

object 类型

object 类型包含了所有对象、数组和函数。

undefined 类型,null 类型

undefinednull 是两种独立类型,它们各自都只有一个值。

如果没有声明类型的变量被赋值为 undefinednull,它们的类型会被推断为 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 类型。

除了 undefinednull 这两个值不能转为对象,其他任何值都可以赋值给 Object 类型。

空对象{}Object 类型的简写形式,所以使用 Object 时常常用空对象代替。

object 类型

object 类型代表可以用字面量表示的对象,只包含对象、数组和函数。

建议总是使用小写类型 object

undefined 和 null 的特殊性

undefinednull 既是值,又是类型。

作为值,任何其他类型的变量都可以赋值为 undefinednull

值类型

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 表示,任何一个类型只要属于 AB,就属于联合类型 A|B

联合类型的第一个成员前面,也可以加上竖杠|,这样便于多行书写。

如果一个变量有多种类型,读取该变量时,往往需要进行“类型缩小”(type narrowing),区分该值到底属于哪一种类型,然后再进一步处理。

交叉类型

交叉类型(intersection types)指的多个类型组成的一个新类型,使用符号&表示。

交叉类型 A&B 表示,任何一个类型必须同时属于 AB,才属于交叉类型 A&B,即交叉类型同时满足 AB 的特征。

交叉类型的主要用途是表示对象的合成。

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 的一个规则是,凡是可以使用父类型的地方,都可以使用子类型,但是反过来不行。

因为子类型继承了父类型的所有特征,所以可以用在父类型的场合。但是,子类型还可能有一些父类型没有的特征,所以父类型不能用在子类型的场合。