Skip to content

Instantly share code, notes, and snippets.

@julenwang
Last active November 1, 2022 09:23
Show Gist options
  • Save julenwang/973841a4b7ad1ccdb0ecc0e9a4b138cc to your computer and use it in GitHub Desktop.
Save julenwang/973841a4b7ad1ccdb0ecc0e9a4b138cc to your computer and use it in GitHub Desktop.
Merge two types, overlapping part use union
type IsPartial<T> = T extends Required<T> ? false : true;
type NoPartial<Sharp1, Sharp2> = IsPartial<Sharp1> & IsPartial<Sharp2> extends true ? false : true;
// Merge two types, overlapping part use union
export type ComposeSharp<
Sharp1,
Sharp2,
InterKeys extends keyof Sharp1 & keyof Sharp2 = keyof Sharp1 & keyof Sharp2
> = UnionToIntersection<
InterKeys extends unknown
? NoPartial<Pick<Sharp1, InterKeys>, Pick<Sharp2, InterKeys>> extends true
? Record<InterKeys, Sharp1[InterKeys] | Sharp2[InterKeys]>
: Partial<Record<InterKeys, Sharp1[InterKeys] | Sharp2[InterKeys]>>
: never
> &
Pick<Sharp1, Exclude<keyof Sharp1, InterKeys>> &
Pick<Sharp2, Exclude<keyof Sharp2, InterKeys>>;
// test cases
type A = { a: 1; b: 2 };
type B = { a: 2; c: 3 };
type C = { a?: 3; d: 4 };
type D = { a?: 4; e: 5 };
type Test1 = ComposeSharp<A, B> extends { a: 1 | 2; b: 2; c: 3 } ? true : false; // true
type Test2 = ComposeSharp<C, D> extends { a?: 3 | 4; d: 4; e: 5 } ? true : false; // true
type Test3 = ComposeSharp<A, C> extends { a?: 1 | 3; b: 2; d: 4 } ? true : false; // true
const test1: Test1 & Test2 & Test3 = true;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment