如何使用 T 在泛型函数中创建泛型对象?

How to create a generic Object in a generic function using T?

早上好,

问题

我正在使用 Typescript 创建一个 angular 应用程序。我想创建一个方法,该方法采用类型参数并将其传递给工厂以使用 cTor 创建一个新实例。如果我知道类型,那效果很好,但如果我不知道,则效果不佳。例如,这有效(第 4 行):

list<T extends IMdmObject>(page = 1, pageSize = 50) {
    this.http.get<T[]>(this.uri).pipe(tap(
        _mdmObject => {
            let _ = _mdmObject.map(x => this.createInstance<MdmCountry>(MdmCountry, x));
            this.mdmStoreController.dispatch(this.ressource, _mdmObject, StoreAction.MERGE);
        }
    )).subscribe();
}

createInstance<T extends AbstractMdmStorable>(concrete: new(mdmObject: IMdmObject) => T, init: IMdmObject): T {
    return new concrete(init);
}

但是如果我改用 T 它就不起作用了:

list<T extends IMdmObject>(page = 1, pageSize = 50) {
    this.http.get<T[]>(this.uri).pipe(tap(
        _mdmObject => {
            let _ = _mdmObject.map(x => this.createInstance<T>(T, x));
            this.mdmStoreController.dispatch(this.ressource, _mdmObject, StoreAction.MERGE);
        }
    )).subscribe();
}

createInstance<T extends AbstractMdmStorable>(concrete: new(mdmObject: IMdmObject) => T, init: IMdmObject): T {
    return new concrete(init);
}

我知道 Typescript 将代码转换为 js,并且 T 在该过程之后不可用。但是有没有办法创建一个扩展 AbstractMdmStorable 的通用实例?

备注

可以将T用作类型,但不能将其用作。所以你不能在此处将 T 作为函数参数传递 this.createInstance<T>(T, x)).

这可以通过依赖注入来解决。您要做的是传递 class(class 本身,而不是 class 的实例)。但与其将其作为 createInstance 函数的参数传递,我建议将 class 存储为工厂的实例变量。在工厂的构造函数中,传入 class 以创建该对象类型的工厂实例。

我不明白你这里的所有类型,但它看起来像这样:

class MyFactory<T extends IMdmObject> {

  constructor(private readonly concrete: new (mdmObject: IMdmObject) => T) {
  }

  list<T extends IMdmObject>(page = 1, pageSize = 50) {
    this.http.get<T[]>(this.uri).pipe(tap(
      _mdmObject => {
        let _ = _mdmObject.map(x => this.createInstance(x));
        this.mdmStoreController.dispatch(this.ressource, _mdmObject, StoreAction.MERGE);
      }
    )).subscribe();
  }

  createInstance(init: IMdmObject): T {
    return new this.concrete(init);
  }
}