extends
类型被extends是类似数组解构一样,将联合类型拆分为单独的类型
例如我们可以实现一个exclude函数,将联合类型中的部分类型剔除掉
type MyExclude<T, U> = T extends U ? never : T
type Data = 'a' | 'b' | 'c'
type Result = MyExclude<Data, 'b'>// 'a' | 'c'
突然一看 T extends U ? never : T 感觉这不就是js的三元运算符吗?
那么最终的结果要么是 nerver 要么就是 T 本身,为啥可以实现exclude的效果呢?
其实一个联合类型在ts看来就相当于一个数组,数组里的元素就是各种类型,
所以 T extends U 就相当于如下代码
type Data // ===> ['a', 'b', 'c']
T extends U // ===> T.forEach(item => item === U)
T extends U ? never : T // ===> T.forEach(item => item === U ? nerver : item)
伪“基础类型“
ts中有一部分的“基础类型“其实也是联合类型 例如常见的 boolean
type Split<T, U = T> = T extends any ? ['T当前被解构出来的值', T, '完整的T的值', U] : []
type Data = Split<boolean>
其实只要是有限的值的集合都会被ts视为联合类型,例如枚举
type Split<T, U = T> = T extends any ? ['T当前被解构出来的值', T, '完整的T的值', U] : []
enum Data {
a = 'a',
b = 'b'
}
type res = Split<Data>
类型整体extends
按照上文,所有的联合类型在extends时都会被解构,然后逐个对比
type res = any extends never ? true : false
但是有的时候不想进行解构而是直接进行整体对比
这时就可以借助[]语法
官方文档如下
所以我们可以把代码修改如下
type res = [any] extends [never] ? true : false