Appearance
自定义守卫(谓语动词 is)
自定义守卫是指通过 {形参} is {类型} 的语法结构,来给返回布尔值的条件函数赋予类型守卫的能力
typescript
function isString(input: any) {
return typeof input === "string";
}
function isNumber(input: any) {
return typeof input === "number";
}
function foo(input: string | number) {
if (isString(input)) {
console.log(input); // 依然是 string | number
} else if (isNumber(input)) {
console.log(input); // 依然是 string | number
}
}类型收窄只能在同一的函数中,如果在不同的函数中就不起作用。
只要我们加上谓语动词:
typescript
function isString(input: any): input is string {
return typeof input === "string";
}
function isNumber(input: any): input is number {
return typeof input === "number";
}
function foo(input: string | number) {
if (isString(input)) {
console.log(input); // string
} else if (isNumber(input)) {
console.log(input); // number
}
}自定义类型守卫在我做一些比较复杂类型判断的时候比较有用
typescript
type Box = {
_v_isBox: boolean;
value: any;
};
function isBox(box: any): box is Box {
return box && box._v_isBox === true;
}
function unWrapBox(box: Box) {
return isBox(box) ? box.value : box;
}上面的这个代码,其实就是简单模拟了一下 Vue3 中isRef和unRef的 ts 代码
typescript
export function isRef(r: any): r is Ref {
return !!(r && r.__v_isRef === true);
}
export function unref<T>(ref: MaybeRef<T> | ComputedRef<T>): T {
return isRef(ref) ? ref.value : ref;
}其实前面讲的字面量的类型检查,typeof,instanceof,in以及自定义守卫在 Typescript 中有统一的称呼,都叫做类型守卫,其目的其实都是在控制流分析的时候,帮助 typescript 收紧类型,便于推断
