在 TypeScript 中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。
目前,TypeScript 支持 3 种字面量类型:字符串字面量类型、数字字面量类型、布尔字面量类型。

  1. {
  2. let specifiedStr: 'this is string' = 'this is string';
  3. let specifiedNum: 1 = 1;
  4. let specifiedBoolean: true = true;
  5. }
  1. {
  2. let specifiedStr: 'this is string' = 'this is string';
  3. let str: string = 'any string';
  4. specifiedStr = str; // ts(2322) 类型 '"string"' 不能赋值给类型 'this is string'
  5. str = specifiedStr; // ok
  6. }
  1. type Direction = 'up' | 'down';
  2. function move(dir: Direction) {
  3. // ...
  4. }
  5. move('up'); // ok
  6. move('right'); // ts(2345) Argument of type '"right"' is not assignable to parameter of type 'Direction'

const 类型推断,会推断为字面量类型

  1. {
  2. const str = 'this is string'; // str: 'this is string'
  3. const num = 1; // num: 1
  4. const bool = true; // bool: true
  5. }

Literal Widening

所有通过 let 或 var 定义的变量、函数的形参、对象的非只读属性,如果满足指定了**初始值**未显式添加类型注解的条件,那么它们推断出来的类型就是指定的初始值字面量类型拓宽后的类型,这就是字面量类型拓宽。

  1. {
  2. let str = 'this is string'; // 类型是 string
  3. let strFun = (str = 'this is string') => str; // 类型是 (str?: string) => string;
  4. const specifiedStr = 'this is string'; // 类型是 'this is string'
  5. let str2 = specifiedStr; // 类型是 'string'
  6. let strFun2 = (str = specifiedStr) => str; // 类型是 (str?: string) => string;
  7. }

如果添加显示类型注解,则不触发类型拓宽。

  1. {
  2. const specifiedStr: 'this is string' = 'this is string'; // 类型是 '"this is string"'
  3. let str2 = specifiedStr; // 即便使用 let 定义,类型是 'this is string'
  4. }

Type Narrowing

在 TypeScript 中,我们可以通过某些操作将变量的类型由一个较为宽泛的集合缩小到相对较小、较明确的集合,这就是 “Type Narrowing”。

  1. {
  2. let func = (anything: any) => {
  3. if (typeof anything === 'string') {
  4. return anything; // 类型是 string
  5. } else if (typeof anything === 'number') {
  6. return anything; // 类型是 number
  7. }
  8. };
  9. }