简体   繁体   English

创建扩展基类的所有类的实例

[英]Create instance of all classes that extend a base class

I have a base class called Editor , I then have items that will extend that class. 我有一个名为Editor的基类,然后我有一些扩展该类的项目。 Is it possible for me to create an instance of all those classes that extend Editor without manually creating them all? 我是否可以创建扩展Editor的所有类的实例而无需手动创建它们?

class Editor<T> {

}

class TransformEditor extends Editor<Transform> {

}

class SomethingEditor extends Editor<Something> {

}

So, in this example the code doesn't know TransformEditor exits, but it is in the codebase, so is it possible to do something where I can get a list of these items, then create an instance of each? 所以,在这个例子中代码不知道TransformEditor退出,但是它在代码库中,所以有可能做一些我可以得到这些项的列表,然后创建每个项的实例的东西吗?

You can wrap all of these classes in a namespace and then you can iterate all of the exported items. 您可以将所有这些类包装在命名空间中,然后可以迭代所有导出的项目。
You can then check for each exported item if it is an instance of the Editor constructor. 然后,如果它是Editor构造函数的实例,则可以检查每个导出的项目。

Something like this: 像这样的东西:

namespace editors {
    export function getEditorClasses(): EditorConstructor<any>[] {
        let list = [];

        Object.keys(this).forEach(name => {
            let obj = this[name];

            if (obj.prototype instanceof editors.Editor) {
                list.push(obj);
            }
        });

        return list;
    }

    export interface EditorConstructor<T> {
        new(): Editor<T>;
    }

    export class Editor<T> {}

    export class TransformEditor extends Editor<string> {}

    export class SomethingEditor extends Editor<boolean> {}
}

console.log(editors.getEditorClasses()); // [function TransformEditor(), function SomethingEditor()]

( code in playground ) 游乐场代码

So there's no way to do this at runtime with TypeScript without adding additional code since there's no way to do this with JavaScript. 所以没有办法在运行时使用TypeScript而不添加额外的代码,因为没有办法用JavaScript做到这一点。

You could use TypeScript's decorators to track the children. 您可以使用TypeScript的装饰器来跟踪孩子。 Here's an extremely simple example: 这是一个非常简单的例子:

class Editor {}

const children = []; // This could be an object that maps parents to children

function TrackChild(constructor: Function) {
  // You could also add more fancy prototype/constructor shenanigans here
  children.push(constructor);
}

@TrackChild 
class TransformEditor extends Editor {}

@TrackChild
class SomethingEditor extends Editor {}

console.log(children);

This decorator could of course become much more sophisticated. 这个装饰者当然可以变得更加复杂。 Here's a very detailed example of tracking a full genealogy with decorators 这是一个用装饰器跟踪完整家谱的非常详细的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM