如何传递构造函数数组

时间:2016-01-10 16:45:42

标签: typescript

如何传递返回某种类型对象的函数数组。换句话说 - 构造函数数组?

我想做的是这样的事情:

    constructor(name: string, systems: Array<Function>){
        this.system = new systems[0]();
    }

但我得到了一个错误Cannot use 'new' with an expression whose type lacks a call or construct signature.,据我所知,我应该以某种方式让编译器知道构造函数返回的对象类型,但我不知道如何。

假设 RJM 的回答,这是我的意思的一个扩展示例:

interface System{
    name: string;
}
interface Component{
    blahblha: string;
}
class Doh implements Component{
    blahblha: string;
}
class Bar implements System{
    name: string = 'bar';
} 

class Blah implements System{
    name: string = 'foo';
}
class Foo {
    systems: Array<System>;
    constructor(bars: Array<()=>System>) {
        for (let i in bars){
            this.systems.push(new bars[i]()); // error: only a void functions can be called with the 'new' keyword.
        }
    }
}
var foo = new Foo([Blah]); // error: Argument of type 'typeof Blah[]' is not assignable to parameter of type '(() => System[]'. Type 'typeof Blah[]' is not assignable to type '() => System'.

我想确保仅使用实现System接口的对象实例填充Foo.systems。所以我应该做错new Foo([Doh]);这样的事情,但即使传递Blah

我也会收到错误

2 个答案:

答案 0 :(得分:6)

如果要实例化类,则必须使用 new 关键字引用它的构造函数。

function factory(constructors: { new (): System }[]) {
    let constructed = constructors.map(c => new c());
}

interface System {
    name: string;
}
class SomeClass implements System {
    name: string;
    constructor() { }
}

class SomeOtherClass implements System {
    name: string;
    constructor() { }
}

let a = factory([SomeClass, SomeClass, SomeClass, SomeOtherClass]);

工厂函数将收到一些构造函数列表,这些构造函数可以创建满足 System 接口的内容。

使用未实现System的类调用该方法将导致您现在收到的错误。

class AnotherClass {}
factory([AnotherClass]); // error

结构类型也有效,因此您不必明确实现接口。

class AnotherClass {
    name: string
}
factory([AnotherClass]);

为了使代码更清晰,您可以将构造函数参数描述的界面移动到接口声明。

// an interface that describes classes that create instances that satisfy the System interface
interface CreatesSystem {
    new (): System
}

interface System {
    name: string;
}

function factory(constructors: CreatesSystem[]) {
    let constructed = constructors.map(c => new c());
}

答案 1 :(得分:0)

如果你使用lambda,它似乎编译并运行正常。

function constructor(name: string, systems: Array<() => void>){
    this.system = new systems[0]();
}