Target
I want write a typescript generics type for Array one-to-one conversion to Object, the function like
transArrayToObject([
[1, 'A'],
[2, 'B'],
] as const)
// type output
{
readonly A: 1;
readonly B: 2;
}
I’ve tried
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)
but the type result is:
{
readonly A: 1 | 2;
readonly B: 1 | 2;
}
This is not what i want. I don't know how write 'A' corresponds to 1,'B' corresponds to 2,
CodePudding user response:
Consider this example:
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
- iterates through Tpl
and infers each element. If element is a tuple with key/value pair, it creates a Record<Key,Value>
, assigns it to Result
and calls Transform
recursively again
If you are interested in tuple manipulations, check my blog