Given the following tuples: (as an example. I could swap to string unions if that would make it possible.)
type Keys = ['North', 'East', 'South', 'West'];
type Values = ['n', 'e', 's', 'w'];
How can I get something similar to this:
type OneToOne<
K extends [...(string | number | symbol)[]],
V extends [...unknown[]]
> = Record<K[0], V[0]>
& Record<K[1], V[1]>
& Record<K[2], V[2]>
& Record<K[3], V[3]>;
But for any arbitrarily long tuples and or unions. Whether K
and V
are tuples or string unions in the end, doesn't make that much of a difference to me. I suppose they would just need to be the same length.
CodePudding user response:
You can use a mapped type to iterate over the keys of Keys
, filtering out only number keys ("0", "1", etc). Then you can use this number key to index into Keys
for the property type (in the as
clause of the mapped type) and get the corresponding value out of Values
:
type Keys = ['North', 'East', 'South', 'West'];
type Values = ['n', 'e', 's', 'w'];
type KetValues<K extends PropertyKey[], V extends Record<keyof K & number, string>> = {
[P in keyof K as P extends `${number}` ? K[P] & PropertyKey : never]: V extends Record<P, infer Prop> ? Prop: never
}
type x = KetValues<Keys, Values>
// type x = {
// North: "n";
// East: "e";
// South: "s";
// West: "w";
// }