【问题标题】:How to create a generic Object in a generic function using T?如何使用 T 在泛型函数中创建泛型对象?
【发布时间】:2020-10-28 06:54:27
【问题描述】:

早上好,

问题

我正在使用 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 的通用实例?

备注

  • AbstractMdmStorable 实现 IMdmObject
  • MdmCountry 扩展 AbstractMdmStorable

【问题讨论】:

    标签: javascript typescript generics factory


    【解决方案1】:

    可以将T 用作类型,但不能将其用作。所以你不能在这里将T 作为函数参数传递this.createInstance&lt;T&gt;(T, x))

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

    我不了解您这里的所有类型,但它看起来像这样:

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

    【讨论】:

    • 嗨琳达,你拯救了我的一天。我对 ts 中的泛型完全陌生,但几周前我在 c# 中写了类似的东西,所以我只是假设它在 ts 中同样有效。再次检查该代码后,我发现我在那里使用反射来获取 cTor。祝你有美好的一天。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    相关资源
    最近更新 更多