条件类型 conditional types
可以通过条件表达式,根据条件表达式判断的结果返回一个类型
⚠️这里也用到了 extends关键字, extends...?:这个是条件表达式,不是一个东西
例子
interface Animal { |
条件类型可以简化一些写法,比如说
interface IdLabel { |
有一个createLabel方法,接收id: number或者name: string类型,返回两个接口类型的数据IdLabel和NameLabel
上面用了穷举,把所有可能的的接收和返回都列出来了
但是可以用条件类型来简化一下
type NameOrId<T extends number | string> = T extends number |
infer关键字 推断关键字(只能在条件类型里面用)
这里有点绕
如何拿一个任意类型数组中一个元素的类型呢
type Flatten<T> = T extends any[] ? T[number] : T; |
上面的做法当然可以,T为一个任意数组类型,任意的数组类型肯定会继承any[]类型,之后使用了索引获取类型(indexed access types)(也就是number,毕竟一个数组的索引都是数字嘛)获得这个T类型数组中元素的类型
这样做扩大了类型,没有做到类型约束
下面是做了类型约束的写法
type Flatten<T> = T extends Array<infer Item> ? Item : T; |
infer Item就是推断出数组中每一个元素的类型,Item是每一个元素的类型
所以这个infer是作为一个类型变量的前关键字的,而不是值变量的关键字。比如说这里不能用typeof代替infer
回归正题,上面写的好处就是明确指定了T类型的数组是不是继承了Array<infer Item>类型数组,比如说
type Str = Flatten<string[]> |
这样做到了绝对的一对一,也就是类型约束
分发条件类型(在条件类型中使用联合类型)
例子
type ToArray<Type> = Type extends any ? Type[] : never; |
给了一个string | number类型,根据条件类型表达式走true条件,会返回string[] | number[]联合类型
传进去的联合类型string | number,和ToArray组装成ToArray<string> | ToArray<number>,再和数组类型组装成数组联合类型string[] | number[]
如果想要一个联合数组类型呢(string | number)[]
需要用方括号,把类型括起来
type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never; |