2015-04-03 103 views
3

如何在打字稿中按预期进行以下工作?如何创建我的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 

的ClassA的性能或功能的无上的dataObject存在MyObject的内侧,我所期待的。例如,我期望dataObject具有myCoolProperty。

我想写一个ProxyObject类,当扩展它的DataObject存储被键入为泛型。

谢谢!

+0

我的猜测是你需要做'obj.dataObject()。myCoolProperty',因为生成的javascript可能会让你的public get属性成为一个函数。 – Pricey 2015-04-03 17:44:15

+0

我相当有信心,这个代码: 'this.dataObject = new Object();' 实际上并没有创建一个新的泛型实例。调试器将dataObject显示为空对象。 – 2015-04-03 17:56:41

+0

对不起,我最初阅读时得到了错误的想法。有这可能会帮助你:https://www.stevefenton.co.uk/Content/Blog/Date/201407/Blog/Creating-TypeScript-Classes-Dynamically/ – Pricey 2015-04-03 18:10:01

回答

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

这会工作,每次扩展ProxyObject时只需要更多的代码。我发布的解决方案是一个简单的恕我直言。这太糟糕了,没有简单的方法来获得通用类型的新实例。谢谢! – 2015-04-03 18:14:57

0

我打开一些较冷的回答这个问题,但现在我只是增加了一个需要重载返回通用的新实例的方法。

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; 
    } 
} 
3

由于打字稿泛型使用类型擦除Ť实现不存在在运行时,可以但传递类中作为一个参数到基座类构造函数,然后使用它来创建新对象。

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运算对象,而不是,ClassA无法实现Object类的符号(因为ClassA中没有Object的构造函数)。 DataObjectBase是一个带有单个构造函数但没有参数的类,虽然ClassA没有明确地派生出来,但它可以满足。