我正在尝试利用TypeScript类型检查,但我坚持使用以下代码:
abstract class Mammal {
abstract breed(other: Mammal);
}
class Dog extends Mammal {
breed(other: Dog) {}
}
class Cat extends Mammal {
breed(other: Cat) {}
}
const toby = new Dog();
const lucy = new Dog();
const luna = new Cat();
toby.breed(lucy); // OK
toby.breed(luna); // Works, but it shouldn't since luna is a Cat!
似乎TypeScript正在执行某种类型的鸭子打字并正在考虑Dog == Cat
。如何让typechecker拒绝此代码?
Sidenote :这就是我在Rust中的表现:
trait Mammal { fn breed(&self, other: &Self); } struct Cat {} impl Mammal for Cat { fn breed(&self, _other: &Self) {} } struct Dog {} impl Mammal for Dog { fn breed(&self, _other: &Self) {} } fn main() { let toby = Dog{}; let lucy = Dog{}; let luna = Cat{}; toby.breed(&lucy); toby.breed(&luna); // expected struct `Dog`, found struct `Cat` }
答案 0 :(得分:1)
TypeScript是structurally typed(感谢@jcalz)。
结构类型背后的想法是,如果它们的成员兼容,则两种类型是兼容的。
不太优雅但有效:您可以添加虚拟属性以在类之间产生一些差异(Playground):
abstract class Mammal {
abstract breed(other: this): void; // Bonus: Here you can make use of Polymorphic this types
}
class Dog extends Mammal {
private dummy1 = undefined;
breed(other: Dog) {}
}
class Cat extends Mammal {
private dummy2 = undefined;
breed(other: Cat) {}
}
const toby = new Dog();
const lucy = new Dog();
const luna = new Cat();
toby.breed(lucy); // OK
toby.breed(luna); // Error
奖励:您可以在基类中使用Polymorphic this types(感谢@jcalz)。
abstract breed(other: this): void;