【问题标题】:Dynamically return a class constructor in TypeScript在 TypeScript 中动态返回类构造函数
【发布时间】:2015-06-26 15:05:35
【问题描述】:

我正在尝试在 TypeScript 中构建一种机制,以基于表示类名称的字符串参数返回类的新实例。基本上,我正在尝试创建一个工厂,只是我不太清楚如何在 TypeScript 中执行此操作。在纯 JS 中,我可以通过将所有类构造函数存储在键/值对象中并调用 new ClassDictionary[className](); 来解决这个问题——这不是最强大的解决方案,但它适用于这种情况。我似乎无法在 TypeScript 中获得正确的类型和强制转换组合来完成此任务。有没有更好的办法?我在 TypeScript 中找不到任何工厂模式的例子,所以现在我只有一个 switch 语句,它既丑陋又不灵活。

【问题讨论】:

标签: javascript typescript factory


【解决方案1】:

您可以为字典中的每个类添加一个函数声明,如下所示(访问:https://www.typescriptlang.org/docs/handbook/declaration-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());

在操场上工作 (Sample)

或者其他方式

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

或带参数:

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

【讨论】:

  • 这可以满足我的需要。我创建了一个带有类引用静态字典的简单工厂类。由于我所有的类都继承自同一个基类,因此我只需要一个函数签名。简单有效,感谢您的想法!
【解决方案2】:

假设你有一个类定义:

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 类的新实例。

【讨论】:

    猜你喜欢
    • 2019-03-23
    • 2019-05-04
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多