为什么typescript会在不相关的类之间隐式转换?

时间:2015-08-19 21:52:21

标签: typescript

Typescript(1.4&任何版本为typescriptlang.org操场提供动力)不会在代码上产生编译器错误,这些代码在形状看起来“相似”的类的隐式类型转换方面似乎是错误的。例如:

class A {
    field: number;
}

class B {
    field: number;
}

function doSomething(a: A): void {
    if (!(a instanceof A))
        throw new Error("Not!")
}

doSomething(new B());

这编译很好然后,当然,虽然看起来打字应该阻止编译,但是会导致运行时错误。类似地,我可以隐式地从接口转换为类而没有错误:

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 });

通过向上面示例中内置对象上尚未找到的类添加方法来打破形状相似性会导致预期的编译错误,而不是隐式转换。

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 });

这是打字稿应该如何表现吗?我们是否应该依赖于instanceof在类似安全的代码中返回预期值?

1 个答案:

答案 0 :(得分:5)

TypeScript使用structural type system。出于类型检查的目的,具有相同属性的类被认为是相同的。最好将instanceof视为关于原型链的运行时检查,而不是关于对象具有或不具有哪些字段的声明。