When presented with two interfaces containing conflicting member types:
interface A { x: number }
interface B { x: string }
It becomes impossible to create an interface that extends both:
interface I extends A, B
// error TS2320: Interface 'I' cannot simultaneously extend types 'A' and 'B'.
// Named property 'x' of types 'A' and 'B' are not identical.
However, it is viable to define an intersection type that integrates A
and B
:
let c = A & B
type C = A & B
// no type errors
Even though, this type cannot be instantiated:
let withNumber: C = { x: 10 }
error TS2322: Type '{ x: number; }' is not assignable to type 'A & B'.
Type '{ x: number; }' is not assignable to type 'B'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
let withString: C = { x: "foo" }
// The same type error, with `number` and `string` reversed
The reason why intersection types do not flag conflicts upon definition remains unclear technically.