網站搜尋

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'.

我想確保 Foo.systems 只會被填充實現了 System 接口的物件實例。所以我應該在做像 new Foo([Doh]); 這樣的事情時收到錯誤,但即使傳入 Blah 時我也收到錯誤

答案#1

如果你想要實例化類別,你必須使用 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 的類別呼叫該方法將導致您目前收到的錯誤。

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

結構型別也可以運作,所以你不必明確地實作這個介面。

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

為了讓程式碼更清晰一些,你可以將針對 constructors 參數描述的介面移到一個 interface 宣告中。

// 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());
}

答案#2

如果你使用 lambda,似乎可以正常編譯和運行。

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