I want to define a type D that requires all fields of interface A, but optionally also embeds the fields of interface B, C or both.
Here is how I'm trying to define it:
interface A {
a1: number;
a2: number;
};
interface B {
b1: number;
b2: number;
};
interface C {
c1: number;
c2: number;
};
type D = A | (A & B) | (A & C) | (A & B & C);
let d: D;
d = {'a1': 1, 'a2': 2};
if ('c1' in d) {
d.c1 = 123;
}
However, typescript doesn't seem to like this, and complains: Property 'c1' does not exist on type 'never'.
In case I've explained the above poorly, I want type D to be able to hold the following values:
{"a1": 1, "a2": 2}
{"a1": 1, "a2": 2, "b1": 3, "b2": 4}
{"a1": 1, "a2": 2, "c1": 5, "c2": 6}
{"a1": 1, "a2": 2, "b1": 3, "b2": 4, "c1": 5, "c2": 6}
But not:
{"a1": 1} // missing field a2
{"a1": 1, "a2": 2, "b2": 4} // missing field b1
{"a1": 1, "a2": 2, "c1": 5} // missing field c2
{"a2": 2, "b1": 3, "c2": 6} // missing fields a1, b2, c1
How can I do this in typescript?