问题
I'm attempting to transform a Tuple union in TypeScript to an object, without losing any types.
Here is an example of how it would work:
type Tuples = ["foo", string] | ["bar", boolean] | ["baz", null];
/*
ideally the type would be:
{
foo: string;
bar: boolean;
baz: null;
}
*/
type AsObject = DoSomething<Tuples>;
A simple solution to the above would be:
type TupleToObject<T extends [string, any]> = { [key in T[0]]: T[1] };
/*
type is:
{
foo: string | boolean | null;
bar: string | boolean | null;
baz: string | boolean | null;
}
*/
type TypesLost = TupleToObject<Tuples>;
However we lose some type information as all values are pulled together in one union type.
I'm looking for a solution using generics that does not lose this type information, and would appreciate any deeper insight into mapping generic tuples in TypeScript.
回答1:
You can get the desired effect, by using Extract
. The basic idea is we will extract from T
the appropriate type from the union that corresponds to the common key
:
type Tuples = ["foo", string] | ["bar", boolean] | ["baz", null];
type TupleToObject<T extends [string, any]> = { [key in T[0]]: Extract<T, [key, any]>[1] };
/*
type is:
{
foo: string;
bar: boolean;
baz: null;
}
*/
type TypesLost = TupleToObject<Tuples>;
来源:https://stackoverflow.com/questions/56988970/tuple-to-object-in-typescript-via-generics