Improved handling of structurally identical classes and instanceof expressions
TypeScript 2.7 improves the handling of structurally identical classes in union types and instanceof
expressions:
- Structurally identical, but distinct, class types are now preserved in union types (instead of eliminating all but one).
- Union type subtype reduction only removes a class type if it is a subclass of and derives from another class type in the union.
- Type checking of the
instanceof
operator is now based on whether the type of the left operand derives from the type indicated by the right operand (as opposed to a structural subtype check).This means that union types andinstanceof
properly distinguish between structurally identical classes.
Example:
class A {}
class B extends A {}
class C extends A {}
class D extends A { c: string }
class E extends D {}
let x1 = !true ? new A() : new B(); // A
let x2 = !true ? new B() : new C(); // B | C (previously B)
let x3 = !true ? new C() : new D(); // C | D (previously C)
let a1 = [new A(), new B(), new C(), new D(), new E()]; // A[]
let a2 = [new B(), new C(), new D(), new E()]; // (B | C | D)[] (previously B[])
function f1(x: B | C | D) {
if (x instanceof B) {
x; // B (previously B | D)
}
else if (x instanceof C) {
x; // C
}
else {
x; // D (previously never)
}
}