什么是类型守卫

A type guard is some expression that performs a runtime check that guarantees the type in some scope.

Typescript在运行时只有Javascript,这时候如何确定变量的类型?

内置类型守卫

Typescript有内置的三个类型守卫:typeofinstanceofArray.isArray

  1. typeof

原始类型可以通过typeof来检查

1
2
3
4
5
6
7
typeof '23' // [LOG]: "string" 
typeof 23 // [LOG]: "number"
typeof true // [LOG]: "boolean"
typeof undefined // [LOG]: "undefined"
typeof Symbol(1) // [LOG]: "symbol"
typeof 10n // [LOG]: "bigint"
typeof null // [LOG]: "object" 注意
  1. instanceof

Javascript中也有instanceof运算符,来检查一个实例是否是某个原型。Typescript中可以用来检查是否是某个Class的实例

1
2
3
4
5
6
7
8
function isSomeClass<T>(instance: any, Class: new (...args: any[]) => T) {
return instance instanceof Class;
}

let today = new Date();
console.log(isSomeClass(today, Date)); // true
let justnow = Date.now();
console.log(isSomeClass(justnow, Date)); // false
  1. Array.isArray

Array中的一个方法,检查是否为数组

自定义类型守卫

除了以上三种内置类型守卫外,对于复合类型,我们需要自定义类型守卫。

如何自定义类型守卫?

  • 类型谓词

    • 什么是类型谓词?

      type predicate类型谓词,一个返回xx is T的函数。谓词就是parameterName is Type. parameterName必须是函数签名中的参数名。

      1
      2
      3
      function isFish(pet: Fish | Bird): pet is Fish {
      return (pet as Fish).swim !== undefined;
      }

      TS中可以使用this is Type来检查class type

  • in 操作符

    JS中可以通过in操作符来检查对象中是否包含某个属性。TS使用in操作符来判断当前类型是联合类型中的哪一个。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    type Human = {
    walk: () => void;
    }

    type Superman = {
    fly: () => void;
    }

    function move(creature: Human | Superman) {
    if ('fly' in creature) {
    return creature.fly();
    }

    return creature.walk();
    }