一、类型谓词是干嘛的?
类型谓词可以有效的帮助我们根据条件缩小类型范围(narrowing)。它与 typeof、instanceof、in类似。但是不同的是typeof、instanceof、in关键字在js中已经是存在的,在ts中使用它们,进行类型收缩时,比较无感知(因为符合js中的用法)
比如
function printAll(strs: string | string[] | null) { if (typeof strs === "object") { for (const s of strs) { 'strs' is possibly 'null'. console.log(s); } } else if (typeof strs === "string") { console.log(strs); } else { // do nothing } }
复制
解释:
-
第一个 if判断中使用typeof判断strs,如果通过的话,那么strs变量可能是数组或者null(ts提示操作也是这样的)
-
第二次if时使用typeof判断,可知现在的strs类型应该是‘string’类型 -
-
最后的else,因为给定strs的类型已经收缩完毕,所以在else分支中为never
二、类型谓词的格式
类型谓词采用parameterName is Type格式,其中parameterName 必须是当前函数中的参数名称
例如
function isFish(pet: Fish | Bird): pet is Fish { // 其中 pet is Fish 就是is类型谓词 return (pet as Fish).swim !== undefined; }
复制
三、应用场景
function runner(params: null | undefined | string): void { if (params == null) { console.log(params); } else { console.log(params); } }
复制
如上代码。在平时写代码时,会进行判断参数是否为null。如果判断的地方多了,可以抽取出一个公共函数来判断。如下
/** * @description isUndef 是否定义 * @param val * @returns { boolean } */ export default function isUndef (val: any): boolean { return val == null; }
复制
并在需要用到的地方导入使用。如下
import isUndef from './isUndef'; function runner(params: null | undefined | string): void { if (isUndef(params)) { console.log(params); } else { console.log(params); } }
复制
会发现,ts不能够根据isUndef函数进行类型收缩,这时候可以使用is类型谓词告诉ts只有当参数为null或者undefined时,返回值才为true,从而进行类型收缩。
```
使用is谓词修改isUndef函数,进而ts正确收缩
/** * @description isUndef 是否定义 * @param val * @returns { boolean } */ export default function isUndef (val: any): val is null | undefined { return val == null; }
复制
如果问题欢迎指出