Reputation: 2747
given
type key = "a" | "b" | "c"
type value = 1 | 2 | 3
I want to generate {a:1, b:2, c:3}
using two union types in above
type A<K,V> = ?????
what is ?????
Upvotes: 1
Views: 195
Reputation: 33041
Technically, it is possible to do. COnsider this example:
type key = "a" | "b" | "c"
type value = 1 | 2 | 3
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
// credits goes to https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
type UnionToOvlds<U> = UnionToIntersection<
U extends any ? (f: U) => void : never
>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
// credits goes to https://stackoverflow.com/questions/53953814/typescript-check-if-a-type-is-a-union#comment-94748994
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true
? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>
: [T, ...A];
type Length<T extends ReadonlyArray<any>> = T extends { length: infer L }
? L
: never;
type CompareLength<
X extends ReadonlyArray<any>,
Y extends ReadonlyArray<any>
> = Length<X> extends Length<Y> ? true : false;
type Callback<T, U> = T extends PropertyKey ? U extends PropertyKey ? Record<T, U> : never : never
// https://catchts.com/tuples#zip
type Zip<
T extends ReadonlyArray<any>,
U extends ReadonlyArray<any>,
Result extends Record<string, any> = {}> =
(CompareLength<T, U> extends true
? (T extends []
? Result
: (T extends [infer HeadT1]
? (U extends [infer HeadU1]
? Result & Callback<HeadT1, HeadU1>
: never)
: (T extends [infer HeadT2, ...infer TailT2]
? (U extends [infer HeadU2, ...infer TailU2]
? Zip<TailT2, TailU2, Result & Callback<HeadT2, HeadU2>>
: never)
: never
)
)
)
: never);
type Keys = UnionToArray<key>;
type Values = UnionToArray<value>
// Record<"a", 1> & Record<"b", 2> & Record<"c", 3>
type Result = Zip<Keys, Values>
I have converted both key
and value
to tuples and then just merged them.
However, you should not do this in your production code. It is UNSAFE. Please see this issue/17944 and my question.
You should never rely on union order as well as Object.keys
order.
Upvotes: 1