确定一个类在TypeScript中实现了哪些接口

时间:2018-04-14 22:23:46

标签: typescript polymorphism

我遇到了一些与类和接口设计各种关系的问题,因为TypeScript不允许某些类型转换为C#。

我当前的层次结构如下:

interface IComponent {}
interface IBehaviour1 {}
interface IBehaviour2 {}
class Component implements IComponent, IBehaviour1 {}
class SpecializedComponent extends Component implements IBehaviour2 {}

在另一个类中,我存储了一个Set<IComponent>集合,我在其中注册了多个ComponentSpecializedComponent个对象。但是在一个函数中,我需要遍历所有函数并调用IBehaviour1特定方法(如果存在)和IBehaviour2特定方法(如果存在)。

由于我经常调用此方法,所以我决定创建设置Set<IBehaviour1>Set<IBehaviour2> - 每次调用addComponent时,我都会适当地对新组件进行分类。

在C#中,这将是这样的:

void AddComponent(IComponent component)
{
    if (component is IBehaviour1)
        behaviour1Components.Add((IBehaviour1)component);
    if (component is IBehaviour2)
        behaviour2Components.Add((IBehaviour2)component);
}

不幸的是,由于IBehaviour1IBehaviour2IComponent不兼容,因此TypeScript不允许进行特定的类型检查/比较。此外,两组都不相交。我很好奇我应该如何存储所有组件,以便我可以调用所有行为方法(如果存在)。

1 个答案:

答案 0 :(得分:2)

在Typescript中,接口只是一个编译时构造。重要的是,如果您需要使用的方法/字段在运行时实际存在于对象上,那就是您应该执行的测试。为了使语法更令人愉悦,您可以使用类型保护来帮助进行类型推断:

interface IComponent { }
interface IBehaviour1 {
  behaviour1Method(): void
}
interface IBehaviour2 {
  behaviour2Method(): void
}
class Component implements IComponent, IBehaviour1 {
  behaviour1Method(): void { }
}
class SpecializedComponent extends Component implements IBehaviour2 {
  behaviour2Method(): void { }
}

function isIBehaviour1(a: any): a is IBehaviour1 {
  return (a as IBehaviour1).behaviour1Method != null;
}
function isIBehaviour2(a: any): a is IBehaviour2 {
  return (a as IBehaviour2).behaviour2Method != null;
}

class Usage {
  behaviour1Components: IBehaviour1[] = []
  behaviour2Components: IBehaviour2[] = []
  addComponent(component: IComponent): void {
    if (isIBehaviour1(component)) {
      this.behaviour1Components.push(component);
    }
    if (isIBehaviour2(component)) {
      this.behaviour2Components.push(component);
    }
  }
}