且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-30 14:25:16

由于typecript泛型是使用类型擦除来实现的,然而,在运行时,您可以将该类作为参数传递给基类构造函数,然后使用它创建新对象。

  export class DataObjectBase {
}

export class ProxyObject< T extends DataObjectBase> {
private _dataObject:T;
构造函数(dataObject?:T,cls?:typeof DataObjectBase){
if(dataObject){
this.dataObject = dataObject;
} else {
//创建通用< T>的新实例这里
this.dataObject =< T>新的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!==未定义

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

类DataObjectBase是必需的,因为如果我将使用typeof Object,ClassA不能已经实现了Object类的符号(就像ClassA中没有Object的构造函数一样)。 DataObjectBase是一个只有一个构造函数的类,它没有参数,ClassA虽然没有明确地从它派生出来,但它完成了。


How can I make the following work as expected in 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";
}

When I do the following:

export class MyObject extends ProxyObject<ClassA> {
}

And then:

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

None of the ClassA properties or functions exist on the dataObject inside the MyObject as I was expecting. For instance, I expected dataObject to have myCoolProperty.

I'm trying to write a ProxyObject class that when extended it's DataObject storage is typed as the generic.

Thanks!!

Since typescript generics are implemented using type erasure T is not present at runtime, you can however pass the class in as a parameter to the base class constructor and then use it to create the new object.

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

This approach still requires a bit of code in the derived classes but at least it keeps all of the logic in the base class

The class DataObjectBase is necessary since if I would have used typeof Object instead, ClassA could not have fulfilled the signarure of the Object class (as in ClassA doesn't have the constructors Object has). DataObjectBase is a class with a single constructor with no arguments, which ClassA, although not explicitly deriving from it, fulfills.