Pretty sure Matt Pocock named this pattern.
Example with a record type:
type Foo = { a: string; b: number; c: boolean; }; /** * | { * key: "a"; * value: string; * } * | { * key: "b"; * value: number; * } * | etc... */ type FooMapped = { [K in keyof Foo]: { key: K; value: Foo[K] }; }[keyof Foo];
We can use this to map union types as well:
type Foo = 'a' | 'b' | 'c'; /** * | { * key: "a"; * value: "a"; * } * | { * key: "b"; * value: "b"; * } * | etc... */ type FooMapped = { [K in Foo]: { key: K; value: K }; }[Foo];