Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does typescript implicitly convert between unrelated classes?

Tags:

typescript

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?

like image 283
Stan Huff Avatar asked Aug 19 '15 21:08

Stan Huff


1 Answers

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.

like image 99
Ryan Cavanaugh Avatar answered Nov 15 '22 04:11

Ryan Cavanaugh