Typescript (1.4 & whatever version is powering the typescriptlang.org playground) does not generate a compiler error on code that seems wrong with respect to implicit type conversion of classes that look "similar" in shape. For instance:
class A {
field: number;
}
class B {
field: number;
}
function doSomething(a: A): void {
if (!(a instanceof A))
throw new Error("Not!")
}
doSomething(new B());
This compiles fine and then, of course, results in a runtime error although it seems typing should have prevented the compile. Similarly I can convert from an interface to a class implicitly without error:
interface I {
field: number;
}
class A implements I {
field: number;
}
function doSomething(a: A): void {
if (!(a instanceof A))
throw new Error("Not!")
}
doSomething({ field: 3 });
Breaking the shape similarity by adding a method to the class not already found on the built-in Object in the above example results in the expected compile error instead of the implicit conversion.
interface I {
field: number;
}
class A implements I {
field: number;
equals(i: I) {
return this.field === i.field;
}
}
function doSomething(a: A): void {
if (!(a instanceof A))
throw new Error("Not!")
}
doSomething({ field: 3 });
Is this how Typescript is supposed to behave? Should we not be able to depend on instanceof
returning an expected value in what seems to be type-safe code?
TypeScript uses a structural type system. Classes with identical properties are considered to be identical for the purposes of typechecking. It's better to think of instanceof
as a runtime check about the prototype chain rather than a statement about what fields an object has or doesn't have.
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