如何为数组到对象的一对一转换编写 TypeScript 泛型类型
目标
我想为数组到对象的一对一转换写一个 TypeScript 泛型类型,这个函数像
transArrayToObject([
[1, 'A'],
[2, 'B'],
] as const)
// type output
{
readonly A: 1;
readonly B: 2;
}
我已经尝试过
type Data = readonly (readonly [number, string])[]
type TransArrayToObject = <TD extends Data>(
data: TD,
) => {
readonly [K in TD[number][1]]: TD[number][0]
}
// Code details are omitted
const transArrayToObject = (() => ({})) as TransArrayToObject
transArrayToObject([
[1, 'A'],
[2, 'B'],
] as const)
但是类型结果是:
{
readonly A: 1 | 2;
readonly B: 1 | 2;
}
这不是我想要的。我不知道如何写‘A’对应1,‘B’对应2,
答案#1
考虑这个例子:
const Tpl = [
[1, 'A'],
[2, 'B'],
] as const
type Tpl = typeof Tpl
type Transform<
Tuple extends readonly any[],
Result extends Readonly<Record<string, any>> = {}> =
(Tuple extends []
? Result // last call
: Tuple extends readonly [infer Head, ... infer Tail]
? (Head extends readonly [infer Value, infer Key]
? (Key extends PropertyKey
? Transform<Tail, Result & Readonly<Record<Key, Value>>>
: never)
: never)
: never)
type Result = Transform<Tpl>
操场
Transform - 遍历 Tpl 并推断每个元素。如果元素是带有键/值对的元组,则创建一个 Record<Key,Value>,将其分配给 Result 并再次递归调用 Transform
如果你对元组操作感兴趣,请查看我的博客
