打字稿没有执行类型检查

时间:2018-02-03 14:12:19

标签: typescript typechecking

我正在尝试利用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`
}

1 个答案:

答案 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;