一、类型谓词是干嘛的?
类型谓词可以有效的帮助我们根据条件缩小类型范围(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;
}
如果问题欢迎指出