在工作中写体操遇到的一个坑,之前一直以为联合类型在转化类型的时候,会被当做分别的类型分开处理,比如
type ToArray<T> = T extends any ? T[] : never
type Foo = ToArray<string | number> // s[] | n[]
可以看到,string 和 number 被分别处理得到了各自的数组类型,并联合成新的类型,
在联合类型里,never 不会被处理如:
type Foo = ToArray<string | never> // s[]
但其实,让 typescript 使用这种类似于分配率的规则转化类型需要符合两个条件:
- 联合的类型是 typescript 泛型
- 必须要有condition type 的判断(形如 A extends B ? C : D)
如果是用泛型推到出的新的类型, 如 T[0], infer R 推到出等等,就不会享受分配率了,下面是一个简单的例子:
type ToArray<T> = T extends any ? T[] : never
type A<T = any> = T[]
type B<T = any> = ToArray<T>
type C<T extends any[]> = ToArray<T[0]>
type D<T extends any[]> = T[0] extends any ? T[0][] : never
type Foo1 = A<string | number> //(s|n)[]
type Foo2 = B<string | number> // s[] | n[]
type Foo3 = C<[string | number]> // s[] | n[]
type Foo4 = D<[string | number]> //(s|n)[]