我有这个
Type T = Params<[Tuple1, Tuple2]> // eg [[string], [number]]
如何制作(展平)
Type Flatten<T> = Params<[string, number]>
答案 0 :(得分:2)
我们可以通过映射类型来做到这一点。考虑代码:
type T = Params<[Tuple1, Tuple2]>
// utility type
type Flatten<T extends any[]> = {
[K in keyof T]: T[K] extends any[] ? T[K][0] : T[K]
}
type Result = Flatten<T>
// evaluates into [string, number]
const a: Result = ['a', 1] // correct value of the type
请注意Flatten
的工作原理:
[K in keyof T]
-表示我们要拥有所有键,因此在元组中说元素T[K] extends any[] ? T[K][0] : T[K]
-我们说如果给定键上的元素的值是一个数组,那么给我一种该数组的第一个元素的类型(索引0),如果不按原样保留它,那么没什么可扁平化的如果元组考虑的元素多于一种,那么上述解决方案将只采用第一种。因此,对于元组[string, number]
,它将产生string
。如果我们想在元组中收集所有可能的类型,我们可以创建更复杂的类型。考虑:
type Flatten<T extends any[]> = {
[K in keyof T]: T[K] extends any[] ? T[K][Exclude<keyof T[K], keyof any[]>] : T[K]
}
T[K] extends any[] ? T[K][Exclude<keyof T[K], keyof any[]>] : T[K]
意味着,如果我们的元素是数组,则可以获取所有元素的类型,但可以删除数组原型中的值的类型。结果Flatten<Params<[string, number]>>
将产生[string | number]
。因此,这取决于您的目标。
最后一个命题是,如果您不考虑其他类型而仅考虑嵌套数组/元组,则可以避免条件类型。考虑最后一个解决方案:
type Flatten<T extends E[], E extends any[] = any[]> = {
[K in keyof T]: T[K][Exclude<keyof T[K], keyof any[]>]
}
上述类型的限制更大,因为它仅与[[]]
一起使用,但更加简洁和具体。