Typescript - 获取接口的所有实现

DOO*_*EMX 11 typescript

我正在寻找一种方法来获取在Typescript中实现某个接口的所有类的列表.

例如,在.Net中,您可以使用反射执行此操作,但我无法找到有关在Typescript中执行相同操作的任何信息.

我想做的代码示例:

interface IControlPanel { }
class BasicControlPanel implements IControlPanel { }
class AdvancedControlPanel implements IControlPanel { }
window.onload = () =>
{
    var controlPanels = IControlPanel.GetImplementations();
    for (var x = 0; x < controlPanels.length; x++)
    {
        document.write(controlPanels[x] + ", "); //outputs: BasicControlPanel, AdvancedControlPanel,
    }
};
Run Code Online (Sandbox Code Playgroud)

如果类很容易实例化,那就更好了.

jca*_*alz 17

正如我在评论中提到的那样,TypeScript 的一个声明的非目标(参见非目标#5)发出依赖于类型系统的JavaScript,因此在运行时没有任何东西可以自动使用来做你想做的事情.

当然,您可以使用TypeScript来帮助您维护几乎可以按照您想要的方式使用的类型的注册表.我建议使用类装饰器,如下所示:

interface IControlPanel {
  // add some methods or something to distinguish from {}
  doAThing(): void;
}

// add a registry of the type you expect
namespace IControlPanel {
  type Constructor<T> = {
    new(...args: any[]): T;
    readonly prototype: T;
  }
  const implementations: Constructor<IControlPanel>[] = [];
  export function GetImplementations(): Constructor<IControlPanel>[] {
    return implementations;
  }
  export function register<T extends Constructor<IControlPanel>>(ctor: T) {
    implementations.push(ctor);
    return ctor;
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,implements IControlPanel您不使用声明类,而是使用@IControlPanel.register:

@IControlPanel.register
class BasicControlPanel {
  doAThing() { }
}

@IControlPanel.register
class AdvancedControlPanel {
  doAThing() { }
}
Run Code Online (Sandbox Code Playgroud)

如果您尝试注册未实现的类,IControlPanel则会收到错误:

// error, doAThing is missing from BadControlPanel
@IControlPanel.register
class BadControlPanel {
  doNothing() { }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以按照自己的方式使用注册表,主要是:

window.onload = () => {
  var controlPanels = IControlPanel.GetImplementations();
  for (var x = 0; x < controlPanels.length; x++) {
    document.write(controlPanels[x].name + ", ");
    const panel = new controlPanels[x]();
    panel.doAThing();
  }
};
Run Code Online (Sandbox Code Playgroud)

我说"大多数"是因为我存储了构造函数,而不是字符串,因为你想要一种方法来实例化它们.您可以获取name字符串的构造函数的属性.并且您可以实例化类,假设它们都采用相同的构造函数参数类型.

希望有所帮助; 祝好运!

  • @jcalz,我刚刚分成不同的文件并停止工作。这是一个示例:https://stackblitz.com/edit/krhey5-z6rrle?file=index.ts (4认同)