在TypeScript中动态返回一个类构造函数。

问题描述 投票:5回答:2

我试图在TypeScript中建立一个机制,基于一个代表类名的字符串参数来返回一个新的类实例。基本上,我想创建一个工厂,只是我不太明白如何在TypeScript中做到这一点。在纯JS中,我可以通过将所有的类构造函数存储在一个key-value对象中,然后调用 new ClassDictionary[className](); - 这不是最稳健的解决方案,但它在这种情况下是可行的。我似乎无法在TypeScript中得到类型和铸造的正确组合来完成这个任务。有更好的方法吗?我在TypeScript中找不到任何工厂模式的例子,所以现在我只有一个位开关语句,这很丑陋而且不灵活。

javascript typescript factory
2个回答
6
投票

你可以为字典中的每一个类添加一个函数声明,这个可以看起来像这样(访问。https:/www.typescriptlang.orgdocshandbookdeclaration-merging.html):

class MyClass { 
    myMethod() { return "my return"; }
}

function factory(className: "Date"): Date;
function factory(className: "Number"): Number;
function factory(className: "MyClass"): MyClass;
function factory(className: string) { 

    var ClassDictionary = {
        "Date": Date,
        "Number": Number,
        "MyClass": MyClass
    };

    return new ClassDictionary[className]();
}

var d = factory("Date");

/* Its a date. */
alert(d.toISOString());

var n = factory("Number");

/* Now a number. */
alert(n.toPrecision());

var c = factory("MyClass");

/* And now MyClass. */
alert(c.myMethod());

游戏场上的作品样品)

或者换一种方式

// ...
var ClassDictionary = { };

ClassDictionary["Date"] = Date;
function factory(className: "Date"): Date;

ClassDictionary["Number"] = Number;
function factory(className: "Number"): Number;

ClassDictionary["MyClass"] = MyClass;
function factory(className: "MyClass"): MyClass;

function factory(className: string) { 
    return new ClassDictionary[className]();
}
// ...

或者用Arguments。

class MyClass {
    constructor(public myReturn: string) { }
    myMethod() { return this.myReturn; }
}

var ClassDictionary = { };

ClassDictionary["Date"] = Date;
function factory(className: "Date"): Date;

ClassDictionary["Number"] = Number;
function factory(className: "Number", value?: number): Number;

ClassDictionary["MyClass"] = MyClass;
function factory(className: "MyClass", myReturn: string): MyClass;

function factory(className: string, valueOrMyReturn?: number | string) { 
   if(valueOrMyReturn) return new ClassDictionary[className](valueOrMyReturn);
    return new ClassDictionary[className]();
}

var d = factory("Date");

/* Its a date. */
alert(d.toISOString());

var n = factory("Number", 42);

/* Now a number. */
alert(n.toPrecision());

var c = factory("MyClass", "This is the answer!");

/* And now MyClass. */
alert(c.myMethod());

1
投票

让我们想象一下,你有一个类的定义。

module UI
{
    export class MyClass
    {
        constructor( data: any )
        {}
     }
}

你可以使用这种结构:

public static CreateController(  data: IControllerData ): any
    {
        return new data.namespace[data.controller]( data.initializationData );
    }

其中data是JS对象,是这样的:

var data = {
            namespace: UI,
            controller: "MyClass"// <- this is the class name
            initializationData: {} // this is the parameters that you want to pass in constructor
}

来创建MyClass类的新实例。

© www.soinside.com 2019 - 2024. All rights reserved.