Skip to content

Instantly share code, notes, and snippets.

@chaance
Created August 12, 2021 03:39
Show Gist options
  • Save chaance/f7008bbaea21a89e753c64a256f7790c to your computer and use it in GitHub Desktop.
Save chaance/f7008bbaea21a89e753c64a256f7790c to your computer and use it in GitHub Desktop.
Merge discriminated union props for better easier destructuring
type SomeProps =
| { action: "START" }
| { action: "STOP"; time: number }
| { action: "PAUSE"; time: number; ref: { current: any } };
function useExample(props: SomeProps) {
let {
action, // "START" | "STOP" | "PAUSE"
time, // number | undefined,
ref // { current: any } | undefined
} = props as Merge<SomeProps>;
return { action, time, ref };
}
// This strategy of merging a discriminated union into a single object type
// courtesy of https://dev.to/lucianbc/union-type-merging-in-typescript-9al
type AllKeys<T> = T extends any ? keyof T : never;
type NonCommonKeys<T extends object> = Subtract<AllKeys<T>, keyof T>;
type PickType<T, K extends AllKeys<T>> = T extends {
[k in K]?: any;
}
? T[K]
: undefined;
type PickTypeOf<T, K extends string | number | symbol> = K extends AllKeys<T>
? PickType<T, K>
: never;
type Merge<T extends object> = { [k in keyof T]: PickTypeOf<T, k> } & //
{ [k in NonCommonKeys<T>]?: PickTypeOf<T, k> };
type Subtract<A, C> = A extends C ? never : A;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment