I have two interfaces A and B and they have one property in common
interface A {
  a: boolean;
  b: number;
  c: string;
  d: boolean;
}
interface B {
  d: string;
}
interface C extends A,B {}
Ideally I want C to be
{
  a: boolean;
  b: number;
  c: string;
  d: boolean | string; <- merged
}
Is there a way to do that? I know I can use Pick to left out the identical key and then extends it but is there any other way to do it?
Since A and B conflict, I believe you can't combine them. If you know what the conflicting keys are, you can omit them when declaring C:
interface A {
  a: boolean;
  b: number;
  c: string;
  d: boolean;
}
interface B {
  d: string;
}
interface C extends Omit<A, 'd'>, Omit<B, 'd'> {
  d: string | boolean
}
let c: C = {
  a: true, b: 3, c: 'a', d: 'a'
}
                        Here you go:
type Merge<X, Y> = {
    [K in (keyof X | keyof Y)]:
        (K extends keyof X ? X[K] : never)
        | (K extends keyof Y ? Y[K] : never)
};
Example usage:
interface A {
  a: boolean;
  b: number;
  c: string;
  d: boolean;
}
interface B {
  d: string;
}
type C = Merge<A, B>;
// Result:
type C = {
    a: boolean;
    b: number;
    c: string;
    d: string | boolean;
}
Playground Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With