Reputation: 18371
I am trying to get the following type: [{a: string}, {b: string}]
by using the type k = 'a' | 'b'
.
What I have tried is to use the following which adds all the keys to the object type as optional
let x: Array<{[key in k]?: string}>
Upvotes: 1
Views: 162
Reputation: 33041
type Union = 'a' | 'b'
// 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 https://stackoverflow.com/users/125734/titian-cernicova-dragomir
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
type Values<T> = T[keyof T]
// Converts union to overloaded function
type UnionToOvlds<U> = UnionToIntersection<
U extends any ? (f: U) => void : never
>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
// credits https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
type UnionToArray<T extends string, A extends unknown[] = []> =
IsUnion<T> extends true
? PopUnion<T> extends string
? UnionToArray<Exclude<T, PopUnion<T>>, [Record<PopUnion<T>, string>, ...A]>
: never
: [Record<T, string>, ...A];
type Result = UnionToArray<Union>
More explanation you will find in links above each type util
If you are interested in more operations over literal types this article will help you
Upvotes: 1