下面是使用TypeScript的语法
interface Animal{
eat():void;
sleep():void;
}
class Mammal implements Animal{
constructor(private name:string){
console.log(this.name, "is alive");
}
eat(){
console.log("Like a mammal");
}
sleep(){
console.log("Like a mammal");
}
}
class Dog extends Mammal{
eat(){
console.log("Like a dog")
}
}
let m: Mammal = new Dog("Prisca"); // looks fine
let d: Dog = new Mammal("abomination"); // This also works
对于变量d
,TypeScript支持结构类型,并且类型Dog
在覆盖后具有Mammal
具有的至少属性(类似)。因此,变量d
仍然可以指向Mammal
类型对象,直到在Dog
类型中添加了另一个属性。
在TypeScript中,如何避免这些陷阱?
答案 0 :(得分:3)
没有办法避免它。结构类型是TypeScript中与JavaScript和JSON互操作的需要。我们需要支付一点费用,以及TypeScript目的的一个后果,即向JavaScript添加类型,同时仍然与它完全兼容,特别是现有的代码库。
在您的示例中,避免它的唯一方法是向Dog
添加Mammal
没有的内容,或者可能使Mammal
成为抽象类,所以它不能直接实例化。在这种情况下,它是合乎逻辑的,因为您可以创建新的Dog
,Cat
,Horse
...但不只是新的Mammal
。
正如Titian和Estus指出的那样,如果你不想让Mammal
抽象出来并想要区分课程,即使你并不真的想要添加任何额外的东西,将添加一个不相关的私有属性,在运行时没有(几乎)任何影响:
private isDog: undefined;