[TS手册学习] 02_类型收窄 Narrowing

发布时间 2023-11-29 22:54:01作者: feixianxing

TS官方手册:TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org)

一个变量如果声明为联合类型,而后续操作需要针对其具体的单一类型做不同处理,这个过程就叫做类型收窄(Narrowing)。

常见的做法或情形有以下:

typeof 类型保护(type guards)

typeof是 JS 中的操作符,需要注意typeof对象、数组、null都会返回object

真值收窄(Truthiness narrowing)

0NaN""0nnullundefined都会被隐式转换为false,属于假值,其它的值是真值。依据这个规则也可以收窄类型。

等值收窄(Equality narrowing)

在 JS 中,全等判断符===要求两边类型一致,以此也可以排除一些类型,从而实现收窄类型。

in 操作符收窄

in操作符检查指定的属性是否在指定的对象或其原型链中。

instanceof 收窄

instanceof运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

赋值语句(Assignments)

TS 可以根据赋值语句的右值的类型收窄左值。

image-20231127221150198

控制流分析(Control flow analysis)

基于可达性的代码分析就是控制流分析,关注代码中的ifwhile等条件控制语句。

如果代码达到了某个区域,而根据条件控制语句可以得知:如果变量X是类型A,无法到达此区域,那么就可以推断出到达此区域的变量X的类型不可能是A。

于是类型收窄。

function padLeft(padding: number | string, input: string) {
  if (typeof padding === "number") {
    return new Array(padding + 1).join(" ") + input;
  }
  return padding + input;
}

在第一个 if 语句里,因为有 return 语句,TypeScript 就能通过代码分析,判断出在剩余的部分 return padding + input ,如果 padding 是 number 类型,是无法达到 (unreachable) 这里的,所以在剩余的部分,就会将 number类型从 number | string 类型中删除掉。