【发布时间】:2020-04-11 01:01:12
【问题描述】:
我有这个
Type T = Params<[Tuple1, Tuple2]> // eg [[string], [number]]
如何制作(展平)
Type Flatten<T> = Params<[string, number]>
【问题讨论】:
标签: typescript typescript-typings typescript-generics
我有这个
Type T = Params<[Tuple1, Tuple2]> // eg [[string], [number]]
如何制作(展平)
Type Flatten<T> = Params<[string, number]>
【问题讨论】:
标签: typescript typescript-typings typescript-generics
我们可以通过映射类型来做到这一点。考虑代码:
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[]>]
}
上面的类型限制更多,因为它只适用于[[]],但更简洁和具体。
【讨论】:
function f(...args: Flatten<T>) {}这样的结果类型