为什么我的TS linter和编译器都不会在这里的test
方法中抱怨大屠杀的类型?看来item: T
约束根本没有得到验证。
在TS 3.8.3和旧版3.2.2上进行了测试:
export class Foo {}
export class Bar {}
export class FooBar {
test() {
const thisIsNotABar: Bar = this.echo<Bar>(new Foo());
}
echo<T>(item: T): T {
return item;
}
}
答案 0 :(得分:2)
这是因为Foo和Bar是兼容的(它们的定义是相同的)。尝试将一个属性添加到另一个属性中,而TypeScript应该会给您一个错误:
export class Foo { a: any }
export class Bar { b: any }
export class FooBar {
test() {
const thisIsNotABar: Bar = this.echo<Bar>(new Foo());
}
echo<T>(item: T): T {
return item;
}
}
给出错误:
类型'Foo'的参数不能分配给'Bar'类型的参数。 属性“ b”在“ Foo”类型中丢失,但在“ Bar”类型中是必需的。
答案 1 :(得分:2)
啊,欢迎来到TypeScript的structural type system。在TypeScript中,如果两个类型具有相同的 shape 或结构,则它们是相同的。它不依赖于类型的名称或声明,例如在nominal type systems中,您可能会更习惯其他语言。
因此,即使您的Foo
和Bar
具有不同的名称和不同的声明,它们的形状仍相同。 em>和结构;即empty object type的值。因此,在TypeScript中,Foo
和Bar
是完全相同的类型。
如果您想将Foo
和Bar
视为不同,则应添加结构的某些不兼容性,例如赋予它们不同的属性:
export class Foo {
foo = ""
}
export class Bar {
bar = ""
}
如果这样做,则应该发生您期望的错误:
const thisIsNotABar: Bar = this.echo<Bar>(new Foo()); // error!
// Foo is not assignable to Bar
好的,希望能有所帮助;祝你好运!