2016-05-31 603 views
14

我正在使用Typescript中的接口来定义仅在某些扩展基类的类上可用的函数。这是代码的简化版本,我到目前为止有:TypeScript - 检查类是否实现接口

class Animal { 
} 

interface IWalkingAnimal { 
    walk(): void; 
} 

class Dog extends Animal implements IWalkingAnimal { 
} 

class Cat extends Animal implements IWalkingAnimal { 
} 

class Snake extends Animal { 
} 

private moveAnimal(animal: Animal) { 
    if (animal instanceof Cat || animal instanceof Dog) { 
     animal.walk(); 
    } 
} 

现在,麻烦的是我会增加更多的“走”的动物,因此moveAnimal功能将增长过大,是可控的。我想这样做是这样的:

private moveAnimal(animal: Animal) { 
    if (animal implements IWalkingAnimal) { 
     animal.walk(); 
    } 
} 

然而,“工具”检查不工作,以及使用接口时,我找不到一个相当于“的instanceof”。在Java中,'instanceof'的使用似乎可以在这里工作,但TypeScript不允许这样做。

TypeScript中是否存在这样的事情,或者这里有更好的方法吗?我正在使用TypeScript 1.8.9。

+0

你为什么不把'IWalkingAnimal'作为动物的一个子类而不是界面?这样你就不会有问题,这是有道理的 – iberbeu

+0

@iberbeu这将适用于这个简化的例子,为了灵活性,我想IWalkingAnimal成为一个界面,所以它不是严格依赖于动物。 Thilo的答案应该可以解决问题。 – MarkLunney

+1

[使用Typescript检查接口类型]可能的重复(https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) –

回答

24

与类不同,接口仅在编译时存在,它们不包含在生成的Javascript中,因此您不能执行instanceof检查。

你可以做IWalkingAnimal动物的子类(和使用instanceof),或者你可以检查,如果有问题的对象有一个walk方法:

if (animal['walk']) {} 

您可以在user defined type guard把这个包(这样编译器可以在if语句中使用时缩小类型,就像instanceof一样)。

/** 
* User Defined Type Guard! 
*/ 
function canWalk(arg: Animal): arg is IWalkingAnimal { 
    return (arg as IWalkingAnimal).walk !== undefined; 
} 


private moveAnimal(animal: Animal) { 
    if (canWalk(animal)) { 
     animal.walk(); // compiler knows it can walk now 
    } 
} 
+2

我建议做'(arg as IWalkingAnimal).walk',这样如果您决定将walk方法重命名为其他类型,那么类型守卫中的代码也会更改。 –

相关问题