如何在 TypeScript 中键入带有类的数组?

新手上路,请多包涵

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

 app.init([TopBar, StatusBar, MainArea]);

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

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

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

问题是因为这些不是实例,TypeScript 不知道它们的类型并抛出错误:

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

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

原文由 Sergei Basharov 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 250
2 个回答

有一个 可用的打字稿游乐场(运行它以获得结果警报)

我们需要的是创建一个自定义的 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))

在这里 检查

原文由 Radim Köhler 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

 function create<T>(c: {new(): T; }): T {
    return new c();
}

其中说“传递到我的 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);

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

app.init([TopBar, StatusBar, MainArea]);

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

原文由 Wade Kalllhoff 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题