先看下面的这个例子:
1、 条件类型
1 | type IType = 'a' | 'b' | 'c' |
2、 分布式条件类型
1 | type Diff2<T, U> = T extends U ? never : T |
3、非裸类型的分布式
1 | type Diff3<T, U> = [T] extends [U] ? never : T |
如果你能正确的说出以上的答案,那么恭喜你可以跳过,否则我们一探究竟:
条件类型
条件类型是ts中非常强大的功能,形如:type R = T extends U ? X : Y
,表示如果 T
是 U
的子类,则返回类型为 X
,否则为 Y
。和三元表达式相似。为了区分下面的分布式条件类型我们需要着重强调下这里的 T 不是以泛型传入的。
根据以上:1
type Diff1 = 'a' | 'b' | 'c' extends 'a' | 'c' ? never : 'a' | 'b' | 'c' // 'a' | 'b' | 'c'
分布式条件类型
在结合联合类型使用时(只针对 extends
左边的联合类型),分布式条件类型会被自动分发成联合类型
分布式条件类型 | 等价于 |
---|---|
string extends T ? A : B |
string extends T ? A : B |
(string | number) extends T ? A : B |
(string extends T ? A : B) | (number extends T ? A : B) |
(string | number | boolean) extends T ? A : B |
(string extends T ? A : B) | (number extends T ? A : B) | (boolean extends T ? A : B) |
根据以上:1
type T1 = Diff<'a','a'|'c'> | Diff<'b','a'|'c'> | Diff<'c','a'|'c'> // never | 'b' | never -> 'b'
划重点:
在官方文档中提到,分布式条件类型是有前提的。条件类型中待检查的类型(即extends
左边的类型)必须是裸类型(naked type parameter
)。即没有被诸如数组,元组或者函数包裹。
根据以上:1
2
3
4type Diff3<T, U> = [T] extends [U] ? never : T
type T2 = Diff3<'a' | 'b' | 'c', 'a' | 'c'> // ?
// 等价于:
type T2 = ['a' | 'b' | 'c'] extends ['a' | 'c'] ? never : 'a' | 'b' | 'c' // 'a' | 'b' | 'c'