Typescript高级数据类型|青训营

27 阅读3分钟

交叉类型(&)

交叉类型是将多个类型合并为一个类型。这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。语法:T & U

其返回类型既要符合 T 类型也要符合 U 类型

联合类型(|)

联合类型与交叉类型很有关联,但是使用上却完全不同。

语法:T | U

其返回类型为连接的多个类型中的任意一个

类型约束(extends)

语法:T extends K

这里的 extends 不是类、接口的继承,而是对于类型的判断和约束,意思是判断 T 能否赋值给 K

可以在泛型中对传入的类型进行约束。

const copy = (value: string | number): string | number => value

// 只能传入 string 或者 number
copy(10)

// 会报错:Argument of type 'boolean' is not assignable to parameter of type 'string | number'
// copy(false)

类型映射(in)

会遍历指定接口的 key 或者是遍历联合类型。

类型谓词(is)

语法:parameterName is Type

parameterName 必须是来自于当前函数签名里的一个参数名,判断 parameterName 是否是 Type 类型。

具体的应用场景可以跟着下面的代码思路进行使用:

看完联合类型的例子后,可能会考虑:如果想要在 start 函数中,根据情况去调用 Bird 的 fly 方法和 Fish 的 swim 方法,该如何操作呢?

首先想到的可能是直接检查成员是否存在,然后进行调用:

function start(pet: Bird | Fish) {    
    // 调用 layEggs 没问题,因为 Bird 或者 Fish 都有 layEggs 方法    
    pet.layEggs();
    
    if ((pet as Bird).fly) {        
        (pet as Bird).fly();    
    } else if ((pet as Fish).swim) {        
        (pet as Fish).swim();    
    }
}

但是这样做,判断以及调用的时候都要进行类型转换,未免有些麻烦,可能会想到写个工具函数判断下:

function isBird(bird: Bird | Fish): boolean {    
    return !!(bird as Bird).fly;
}

function isFish(fish: Bird | Fish): boolean {    
    return !!(fish as Fish).swim;
}

function start(pet: Bird | Fish) {    
    // 调用 layEggs 没问题,因为 Bird 或者 Fish 都有 layEggs 方法    
    pet.layEggs();
    if (isBird(pet)) {     
        (pet as Bird).fly();    
    } else if (isFish(pet)) {      
        (pet as Fish).swim();    
    }
}

待推断类型(infer)

可以用 infer P 来标记一个泛型,表示这个泛型是一个待推断的类型,并且可以直接使用。可以应用于判断 T 是否能赋值给 (param: infer P) => any,并且将参数推断为泛型 P,如果可以赋值,则返回参数类型 P,否则返回传入的类型。

原始类型保护(typeof)

语法:typeof v === "typename" 或 typeof v !== "typename"

用来判断数据的类型是否是某个原始类型(number、string、boolean、symbol)并进行类型保护

"typename"必须是 "number", "string", "boolean"或 "symbol"。但是 TypeScript 并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。

类型保护(instanceof)

与 typeof 类似,不过作用方式不同,instanceof 类型保护是通过构造函数来细化类型的一种方式。

instanceof 的右侧要求是一个构造函数,TypeScript 将细化为:

此构造函数的 prototype 属性的类型,如果它的类型不为 any 的话

构造签名所返回的类型的联合。

索引类型查询操作符(keyof)

语法:keyof T

对于任何类型 T, keyof T 的结果为 T 上已知的 公共属性名 的 联合

索引访问操作符(T[K])

语法:T[K]

类似于 js 中使用对象索引的方式,只不过 js 中是返回对象属性的值,而在 ts 中返回的是 T 对应属性 P 的类型