【问题标题】:How can I create a new instance of the generic type of my Typescript class?如何创建我的 Typescript 类的泛型类型的新实例?
【发布时间】:2015-04-03 17:15:55
【问题描述】:

如何在 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 存储时,它被键入为泛型。

谢谢!!

【问题讨论】:

标签: generics typescript


【解决方案1】:

因为 typescript 泛型是使用类型擦除实现的

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 没有显式地从它派生,但它实现了。

【讨论】:

    【解决方案2】:

    &lt;T&gt; 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());
              }
        }
    }
    

    【讨论】:

    • 这可行,只是每次我扩展 ProxyObject 时都需要更多代码。我发布的解决方案有点简单恕我直言。太糟糕了,没有一种简单的方法来获取通用类型的新实例。谢谢!
    【解决方案3】:

    我对这个问题的一些更酷的答案持开放态度,但现在我只是添加了一个需要重载以返回 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      • 1970-01-01
      相关资源
      最近更新 更多