我正在寻找一种方法来获取在 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,
}
};
如果类很容易实例化,那就更好了。
正如我在评论中提到的,这是 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;
}
}
现在,您不用声明类
implements IControlPanel
,而是使用 @IControlPanel.register
:
@IControlPanel.register
class BasicControlPanel {
doAThing() { }
}
@IControlPanel.register
class AdvancedControlPanel {
doAThing() { }
}
如果您尝试注册一个未实现
IControlPanel
的类,您将收到错误:
// error, doAThing is missing from BadControlPanel
@IControlPanel.register
class BadControlPanel {
doNothing() { }
}
现在您可以按照您想要的方式使用注册表,主要是:
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();
}
};
我说“大部分”是因为我存储了构造函数,而不是字符串,因为您想要一种实例化它们的方法。您可以获取字符串构造函数的
name
属性。您可以实例化这些类,假设它们都采用相同的构造函数参数类型。