如何在TypeScript中使用类键入数组?

Ser*_*rov 6 javascript typescript

我有一个通过运行如下方法进行初始化的应用程序.init(params)

app.init([TopBar, StatusBar, MainArea]);
Run Code Online (Sandbox Code Playgroud)

其中TopBarStatusBarMainArea是类,而不是类的实例。这些类中的每一个都实现相同的接口IComponent

我想从.init(params)方法中传递的类实例化对象,如下所示:

init(params: IComponent[]): void {
    params.map(function (component) {
        let comp = new component();
        this.components[comp.constructor.name] = comp;
    }, this);
Run Code Online (Sandbox Code Playgroud)

问题在于,由于这些不是实例,因此TypeScript不知道其类型并引发错误:

错误TS2345:类型'((typeof TopBar | typeof StatusBar | typeof MainArea)[]'的参数不能分配给'IComponent []'类型的参数。

如何修复代码,以便可以将实现某些接口的类的数组传递给方法?

小智 7

Typescript 支持类类型泛型(TypeScript 文档)。他们的例子是:

function create<T>(c: {new(): T; }): T {
    return new c();
}
Run Code Online (Sandbox Code Playgroud)

其中表示“将create一个类传递到我的方法中,该类在构造时将返回我想要的类型 T”。此签名将阻止您尝试传递任何非 T 类型的类类型。

这很接近我们想要的,我们只需要对其进行调整,使其成为您的项目和项目的数组IComponent

public init(components: {new(): IComponent;}[]): void {
    // at this point our `components` variable is a collection of
    // classes that implement IComponent

    // for example, we can just new up the first one;
    var firstComponent = new components[0]();
}, this);
Run Code Online (Sandbox Code Playgroud)

有了方法签名,我们现在可以像这样使用它

app.init([TopBar, StatusBar, MainArea]);
Run Code Online (Sandbox Code Playgroud)

我们传入实现的类型数组IComponent


Rad*_*ler 6

有一个工作打字稿游乐场(运行它以获取结果警报)

我们需要的是创建一个自定义type InterfaceComponent. 这将被预期为init()方法的数组

interface IComponent { }
class TopBar    implements IComponent { }
class StatusBar implements IComponent { }
class MainArea  implements IComponent { }

// this is a type we want to be passed into INIT as an array
type InterfaceComponent = (typeof TopBar | typeof StatusBar | typeof MainArea);

class MyClass {

  components: {[key:string] : IComponent } = {};

  init(params: (InterfaceComponent)[]): void {
    params.map((component) => {
        let comp = new component();
        this.components[comp.constructor["name"]] = comp;
    }, this);
  }
}

let x = new MyClass();
x.init([TopBar, StatusBar, MainArea])

alert(JSON.stringify(x.components))
Run Code Online (Sandbox Code Playgroud)

在这里检查