Skip to content

Instantly share code, notes, and snippets.

@betafcc
Last active January 11, 2020 13:36
Show Gist options
  • Save betafcc/4d3654f3fa814c81d58c6e971e37d2e5 to your computer and use it in GitHub Desktop.
Save betafcc/4d3654f3fa814c81d58c6e971e37d2e5 to your computer and use it in GitHub Desktop.
Interesting TypeScript utilities
// Spread<{x: number} & {y: string}> -> {x: number, y: string}
export type Spread<T> = ReturnType<() => { [P in keyof T]: T[P] }>
// Merge<{x: number} | {y: string}> -> {x: number} & {y: string}
export type Merge<T> = (T extends any ? (k: T) => void : never) extends (k: infer U) => void
? U
: never
// Values<{x: number, y: string}> -> number | string
export type Values<T> = T[keyof T]
// Invert<{a: 1, b: 2, c: 3}> -> {1: 'a', 2: 'b', 3: 'c'}
export type Invert<T extends Record<keyof any, keyof any>> =
Spread<Merge<Values<{[K in keyof T]: { [P in T[K]]: K }}>>>
// Rename<{x: number, y: string}, {x: 'a', z: 'foo'}> -> {a: number, y: string}
export type Rename<T, Names extends Record<keyof any, keyof any>> =
Spread<
Omit<T, keyof Names> &
Merge<Values<{ [K in Extract<keyof T, keyof Names>]: { [NewK in Names[K]]: T[K] } }>>
>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment