给出这两种类型
type keys = ['name', 'age', 'height']
type valueTypes = [string, number, number]
如何创建压缩的对象类型? {name: string, age: number, height: number}
?
这是我的尝试:
type Zip<K, V> = {
[KK in keyof K]: {
[VV in keyof V]: K[KK] extends string ? Record<K[KK], V[VV]> : never
}
}
答案 0 :(得分:1)
type Shift<T extends any[]> = ((...args: T) => any) extends ((first: any, ...rest: infer R) => any) ? R : never;
type ConvertIntoObject<Keys extends any[], Values extends any[]> = _ConvertIntoObject<Keys, Values, {}>
type _ConvertIntoObject<Keys extends any[], Values extends any[], Acc extends {}> = {
0: Acc,
1: _ConvertIntoObject<Shift<Keys>, Shift<Values>, {
[K in Keys[0]]: Values[0]
} & Acc>
}[Keys['length'] extends 0 ? 0 : 1];
type a = ["e", "i", "o"]
type b = [1, 2, 3]
type c = ConvertIntoObject<a, b> // type c is { e: 1, i: 2, o: 3}
答案 1 :(得分:0)
通常,术语“ zip”是指convolution,您可以在其中将数组的有序对(或三元组等)变成有序对(或三元组等)的数组。有关示例,请参见Python's zip()
,Haskell's zip
。
在TypeScript中压缩元组类型的一种方法是,忽略元组长度不同的边缘情况,如下所示:
type ZipTuple<T extends readonly any[], U extends readonly any[]> = {
[K in keyof T]: [T[K], K extends keyof U ? U[K] : never]
}
我们只是使用TS3.1中添加的mapped tuple/array feature。
这将产生以下结果:
type Keys = ['name', 'age', 'height']
type Values = [string, number, number]
type KVTuple = ZipTuple<Keys, Values>;
// type KVTuple = [["name", string], ["age", number], ["height", number]]
为此,我们可以定义KeyValTuplesToObject<K, V>
,它接受键的元组K
和值的相同长度的元组V
并生成对象类型,其中每个键都映射到对应值:
type KeyValTuplesToObject<K extends readonly PropertyKey[], V extends readonly any[]> =
ZipTuple<K, V>[number] extends infer Z ?
[Z] extends [[any, any]] ? { [P in Z[0]]: Extract<Z, [P, any]>[1] } : never : never
首先使用ZipTuple
将键和值元组转换为键值对的元组,然后用[number]
对其进行索引,以得到键值元组作为并集,然后进行一种映射类型,可迭代这些元组中的所有键,并从相应元素中提取值。
使用之前相同的Keys
和Values
,结果如下:
type KVObject = KeyValTuplesToObject<Keys, Values>
/* type KVObject = {
name: string;
age: number;
height: number;
} */
对我很好。希望能有所帮助;祝你好运!