Type Guard 和 Type Predicate 的小细节

1,632 阅读1分钟

最近通过阅读官方的 Handbook 学习TypeScript, 记录在区分不同Union Type时使用Type Guard技术的一些细节。

Type Guard 和 Type Predictate

形如isDog的函数就是Type Guard,它的返回值animal is Dog类型为Type Predicate,这二者缺一不可。

interface Dog { 
    type: 'dog',
    bark: 'wang',
}
interface Fish {
    type: 'fish',
    swim: 'gududgu',
}
type Animal = Dog | Fish
function isDog(animal:any): animal is Dog {
    return animal.type === 'dog'
}

主要作用是类型推断,除了用在 if 语句里,其它例如 while 和 for 语句也可以使用

function doSth(animal:Animal) {
    animal.bark // ×, bark属性不在 Animal 里
    animal.swim // ×, 同上
    if(isDog(animal)){
        animal.bark // √ 没有问题
    } else {
        animal.swim // √ 没有问题
    }
}

Type Guard用在 if 语句中可以看出,它的返回值类型Type Predicate其实也就是 boolean 类型,但是在使用中有两个小细节需要注意

1. 定义Type Guard时必须使用Type Predicate

function isDog(animal:any):boolean {
    ... // 这样定义则没有类型推断作用
}

2.使用时不能存在类型转换。

function doSth(animal:Animal) {
    if(isDog(animal)===true){
        animal.bark // × 无法类型推断
    } else {
        animal.swim // × 无法类型推断
    }
}