Typescript(Angular2)泛型构造函数工厂

时间:2017-05-04 09:24:03

标签: angular generics typescript

我正在使用typescipt 2。 我正在编写一些解析器方法,它从服务器接收模型并将其转换为我可以使用的实例。

代码:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            // Not implemented here
            return false;
        default:
            break;
    }
    searchView.setOnQueryTextListener(queryTextListener);
    return super.onOptionsItemSelected(item);
}

并假设我有以下课程

export interface Constructable {
     copy(other : any) : void;
}

//in my Convert class which converts server responses to model
private static _parseT<T extends Constructable>(obj : any) : T {
    let instance = Object.create(T); // the row of the compile-time error
    instance.constructor.apply(instance);
    instance.copy(obj);
    return instance;
}

我有编译时错误

  

找不到名字T

现在,我确定它不是语法,但我找不到。

清除事情。这就是用法的样子:

export class Foo implements  Constructable {
    private test : string  = null;

    public copy(other:any) : void {
        this.test = other.test;
    }
}

注意

虽然一些工厂模式可以解决这个问题,但我真的想继续使用public static ParseFoo(data: any) : Foo{ return Convert._parseT<Foo>(data.mResult); // data is a server response object } 方法,而不是创建并返回实例的Copy

1 个答案:

答案 0 :(得分:2)

您收到此错误是因为T是一种类型,而不是class

打字稿中的class具有此签名:new(...args: any[]) => any,您可以在其上调用Object.create,因为T在您的函数中不是变量,您可以&#39;做这样的事情。

要实现您想要做的事情,您必须将class本身作为参数传递:

private static _parseT<T extends Constructable>(clazz: new(...args: any[]) => any, obj : any) : T {
    let instance = <Constructable>new clazz();
    instance.copy(obj);
    return <T>instance;
}

这样,唯一可以接受的clazz是构建你的类型的那个。{/ p>

你可以举一个关于我最近在github做的事情的例子(不是一个有角度的项目,但你的问题是纯粹的打字稿问题)。

此功能的示例调用:

let FooInstance = this._parseT<FooClass>(FooClass, myObj);

此处,第一个FooClass是类型,而第二个class本身就是function QueryAcc(callback){ conn.query("SELECT Id, Name FROM Account limit 1", function(err, result) { if (err) { console.error(err); } else{ var records = []; console.log("fetched : " + result.records); for (var i=0; i<result.records.length; i++) { var record = result.records[i]; records.push(record); } console.log("First Name: " + result.records[0].Name); callback(records); } }); } var intents = new builder.IntentDialog(); intents.matches(/^QueryAcc/i, [ function (session) { Salesforce.QueryAcc(function(results){ console.log('the response--'+results.response); }); } ]);

由于您无法在运行时获取类的类,因此它是您从类型构造类的唯一解决方案。