如何创建我的Typescript类的泛型类型的新实例?

时间:2015-04-03 17:15:55

标签: generics typescript

如何在Typescript中按预期进行以下工作?

export class ProxyObject<T> {
    private _dataObject:T;
    constructor(dataObject?:T) {
        if (dataObject) {
            this.dataObject = dataObject;
        } else {
            //create a new instance of the generic <T> here
            this.dataObject = <T> new Object();
        }
    }
    set dataObject(dataObject:T) {
        this._dataObject = dataObject;
    }
    get dataObject():T {
        return this._dataObject;
    }
}

export class ClassA {
   myCoolProperty = "My Cool Property";
}

当我执行以下操作时:

export class MyObject extends ProxyObject<ClassA> {
}

然后:

var obj = new MyObject();
obj.dataObject.myCoolProperty === undefined

MyObject中的dataObject上没有任何ClassA属性或函数,正如我所期望的那样。例如,我希望dataObject具有myCoolProperty。

我试图编写一个ProxyObject类,在扩展时,它的DataObject存储被输入为泛型。

谢谢!

3 个答案:

答案 0 :(得分:4)

由于使用类型擦除实现了typescript泛型,因此在运行时不存在T,但是您可以将该类作为参数传递给基类构造函数,然后使用它来创建新对象。

export class DataObjectBase {
}

export class ProxyObject<T extends DataObjectBase> {
    private _dataObject: T;
    constructor(dataObject?: T, cls?: typeof DataObjectBase) {
        if (dataObject) {
            this.dataObject = dataObject;
        } else {
            //create a new instance of the generic <T> here
            this.dataObject = <T> new cls();
        }
    }
    set dataObject(dataObject: T) {
        this._dataObject = dataObject;
    }
    get dataObject(): T {
        return this._dataObject;
    }
}



export class ClassA {
    myCoolProperty = "My Cool Property";
}


export class MyObject extends ProxyObject<ClassA> {
    public constructor(dataObject?: ClassA) {
        super(dataObject, ClassA);
    }
}

new MyObject();
obj.dataObject.myCoolProperty !== undefined

这种方法仍然需要派生类中的一些代码,但至少它保留了基类中的所有逻辑

类DataObjectBase是必要的,因为如果我将使用typeof Object,则ClassA无法实现Object类的符号(因为在ClassA中没有构造函数Object具有)。 DataObjectBase是一个具有单个构造函数且没有参数的类,ClassA虽然没有明确地从中派生,但却满足。

答案 1 :(得分:0)

<T> new Object()不会创建T的实例。试试这个:

class MyObject extends ProxyObject<ClassA> {
    constructor(dataObject?: ClassA) {
        if (dataObject) {
              super(dataObject);
          } else {
              //create a new instance of the generic <T> here
              super(new ClassA());
          }
    }
}

答案 2 :(得分:0)

我对这个问题的答案很开心,但是现在我只是添加了一个需要重载的方法来返回Generic的新实例。

export class ProxyObject<T> {

    private _dataObject:T;

    constructor(dataObject?:any) {
        if (dataObject) {
            this.dataObject = dataObject;
        } else {
            this.dataObject = this.createEmptyDataObject();
        }
    }

    protected createEmptyDataObject():T {
        throw new Error('You must overload the createEmptyDataObject() method on ProxyObject');
        return null;
    }

    set dataObject(dataObject:T) {
        this._dataObject = dataObject;
    }

    get dataObject():T {
        return this._dataObject;
    }
}

例如,这是一个例子:

export class TabularRecord extends ProxyObject<TabularRecordDO> {

    createEmptyDataObject():TabularRecordDO {
        return new TabularRecordDO();
    }

    get record():any {
        return this.dataObject.record;
    }

    set record(record:any) {
        this.dataObject.record = record;
    }
}