元组

我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素。

TypeScript 的元组无法在运行时约束所谓的“元组”像真正的元组一样,保证元素类型、长度不可变更)。

这里需要注意:数组类型的值只有显示添加了元组类型注解后(或者使用 as const,声明为只读元组),TypeScript 才会把它当作元组,否则推荐出来的类型就是普通的数组类型。

  1. const x: [number, string] = [1, 'setState'];
  2. const y: [number, string] = [1, 2];
  3. // 提示 ts(2322) 不能将类型“number”分配给类型“string”。

需要返回的值的个数超过2个时,会更偏向于使用对象作为返回值

当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型

  1. let tom: [string, number];
  2. tom = ['Tom', 25];
  3. tom.push('male');
  4. tom.push(true);
  5. // Argument of type 'true' is not assignable to parameter of type 'string | number'.

unknown

unknownany 的主要区别是 unknown 类型会更加严格:在对 unknown 类型的值执行大多数操作之前,我们必须进行某种形式的检查。而在对 any 类型的值执行操作之前,我们不必进行任何检查。

  1. let value: unknown;
  2. let value1: unknown = value; // OK
  3. let value2: any = value; // OK
  4. let value3: boolean = value; // Error
  5. let value4: number = value; // Error
  6. let value5: string = value; // Error
  7. let value6: object = value; // Error
  8. let value7: any[] = value; // Error
  9. let value8: Function = value; // Error

使用 unknown 后,TypeScript 会对它做类型检测。但是,如果不缩小类型(Type Narrowing),我们对 unknown 执行的任何操作都会出现如下所示错误:

  1. let result: unknown;
  2. result.toFixed(); // 提示 ts(2571) 对象的类型为 "unknown"。

而所有的类型缩小手段对 unknown 都有效,如下代码所示:

  1. let result: unknown;
  2. if (typeof result === 'number') {
  3. result.toFixed(); // 此处 hover result 提示类型是 number,不会提示错误
  4. }

包括 typeof 运算符,instanceof 运算符和自定义类型保护函数。

void、undefined、null

  • void 类型,仅适用于表示没有返回值的函数
  • undefined 的最大价值主要体现在接口类型上,它表示一个可缺省、未定义的属性
  • null 的价值主要体现在接口制定上,它表明对象或属性可能是空值

可以把 undefined 值或者类型是 undefined 的变量赋值给 vod 类型变量 反过来,类型是 void 但值是 undefined 的变量不能赋值给

never

never 表示永远不会发生值的类型,这里我们举一个实际的场景进行说明。

  1. function ThrowError(msg: string): never {
  2. throw Error(msg);
  3. }

以上函数因为永远不会有返回值,所以它的返回值类型就是 never。

never 是所有类型的子类型,它可以给所有类型赋值,如下代码所示。

  1. let Unreachable: never = 1; // ts(2322)
  2. Unreachable = 'string'; // ts(2322)
  3. Unreachable = true; // ts(2322)
  4. let num: number = Unreachable; // ok
  5. let str: string = Unreachable; // ok
  6. let bool: boolean = Unreachable; // ok

但是反过来,除了 never 自身以外,其他类型(包括 any 在内的类型)都不能为 never 类型赋值。