edkeveked
edkeveked

Reputation: 18371

type of an array of object whose key is in template Literal Types

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

Answers (1)

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>

Playground

Blog

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

Related Questions