Tuple To Union
问题描述
实现泛型TupleToUnion<T>,它返回元组所有值的合集。
例如
type Arr = ['1', '2', '3']
type Test = TupleToUnion<Arr> // expected to be '1' | '2' | '3'
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
let v1 = [1, 2, '3'] as const // 自己加的
type cases = [
Expect<Equal<TupleToUnion<[123, '456', true]>, 123 | '456' | true>>,
Expect<Equal<TupleToUnion<[123]>, 123>>,
Expect<Equal<TupleToUnion<typeof v1>, 1 | 2 | '3'>> // 自己加的
]
// ============= Your Code Here =============
// 答案1
type TupleToUnion<T> = T[number & keyof T]
// 答案2
type TupleToUnion<T extends readonly any[]> = T[number]
// 答案3
type TupleToUnion<T extends readonly any[]> = T extends readonly (infer R)[] ? R : never
// 答案4
type TupleToUnion<T extends readonly any[]> = T extends readonly [infer first, ...infer rest]? first | TupleToUnion<rest>: never;
这道题的思路也很简单,元组实际上是只读的固定长度的数组,不可以修改其内容和类型,如何将其转为联合类型,只需要循环数组即可,前面的文章提过,keyof 得到的是数组的索引,T[number] 得到的是数组的具体项,比如 v1中 T[0] 得到的就是 1,T[1] 得到的就是 2,T[2] 得到的就是 ‘3’,联合类型就是“或者” 的含义,1 或者 2 或者“3”,所以 答案1 和 答案2 差不多。答案3 是使用 infer 关键字,获取到具体的值,答案4 是使用递归的方式,先将元组分出第一个元素,得到其类型,再将后面的元素递归,重复得到第一个元素的类型后使用 | 运算符连接起来。