TypeScript - 检查类是不是实现了接口

Posted

技术标签:

【中文标题】TypeScript - 检查类是不是实现了接口【英文标题】:TypeScript - Check if Class implements an InterfaceTypeScript - 检查类是否实现了接口 【发布时间】:2016-09-29 08:11:47 【问题描述】:

我正在使用 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();
    

但是,“implements”检查不起作用,并且在使用接口时我找不到与“instanceof”等效的选项。在 Java 中,'instanceof' 的使用似乎在这里可以工作,但 TypeScript 不允许这样做。

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

【问题讨论】:

你为什么不让 IWalkingAnimal 作为 Animal 的子类而不是接口?这样你就不会有问题了,这是有道理的 @iberbeu 这将适用于这个简化的示例,为了灵活性,我希望 IWalkingAnimal 是一个接口,因此它不严格绑定到 Animal。 Thilo 在下面的回答应该可以解决问题。 Interface type check with Typescript的可能重复 【参考方案1】:

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

您可以将 IWalkingAnimal 设为 Animal 的子类(并使用 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
    

【讨论】:

我建议使用(arg as IWalkingAnimal).walk,这样如果你决定将 walk 方法重命名为其他名称,那么类型保护中的代码也会随之改变。

以上是关于TypeScript - 检查类是不是实现了接口的主要内容,如果未能解决你的问题,请参考以下文章

检查对象是不是在运行时使用 TypeScript 实现接口

如何检查对象是不是实现了接口? [复制]

TypeScript 类使用联合类型字段实现接口导致错误 (2322)

检查实例的类是不是实现了接口?

将 json 解析为 typescript 中的接口并检查是不是正常

TypeScript--泛型