types-kit.deepmerge.md

September 4, 2023 ยท View on GitHub

Home > types-kit > DeepMerge

DeepMerge type

Merge two types into a new type. Keys of the second type will assign keys of the first type.

Signature:

export type DeepMerge<A, B> = A extends readonly unknown[]
  ? B extends readonly unknown[]
    ? DeepMergeTuple<A, B>
    : Simplify<
        StrictOmit<A, Extract<Keys<A>, Keys<B>>> & {
          [P in keyof B as P extends Keys<B> ? P : never]: P extends Keys<A>
            ? B[P] extends infer V
              ? V extends V
                ? If<And<[IsObject<V>, IsObject<A[P]>]>, DeepMerge<A[P], V>, V>
                : never
              : never
            : B[P]
        }
      >
  : Simplify<
      StrictOmit<A, Extract<Keys<A>, Keys<B>>> & {
        [P in keyof B as P extends Keys<B> ? P : never]: P extends Keys<A>
          ? B[P] extends infer V
            ? V extends V
              ? If<And<[IsObject<V>, IsObject<A[P]>]>, DeepMerge<A[P], V>, V>
              : never
            : never
          : B[P]
      }
    >

References: DeepMergeTuple, Simplify, StrictOmit, Keys, If, And, IsObject, DeepMerge

Example

    interface Foo {
        a: {
          c: number
          d: boolean
        };
        b: string;
    };
    interface Bar {
        a: {
          d: string
        };
    };
    // Expect: { a: { c: number, d: string }, b: string }
    type NewProps = DeepMerge<Foo, Bar>