【问题标题】:TypeScript: pass generic type as parameter in generic classTypeScript:在泛型类中将泛型类型作为参数传递
【发布时间】:2016-05-27 11:29:16
【问题描述】:

打字稿: 我在 DataProvider 类中有一个方法,方法是 getTableData:

public static getTableData<T extends DataObject>(type: { new(): T}): Array<T> { ... }

这在我编码时完美运行:

let speakers = DataProvider.getTableData(Speaker);  // where Speaker is a class

现在我想从一个通用类中调用它:

export class ViewModelBase<T extends DataObject> {   
  public getData(): Array<T> {
    return <T[]> DataProvider.getTableData(T);
  }
}

现在我得到一个 Cannot find name 'T' 错误,因为我传递给 getTableData 的 T 参数。 getTableData 应该如何调用?

更新: 在@Paleo 的帮助下,我想出了这个:

export class ViewModelBase<T extends DataObject> {   

  constructor(private dataObjectClass: { new(): T}){}

  public getTableData(): Array<T> {
    return <T[]> DataProvider.getTableData<T>(this.dataObjectClass);
  }
}

问题是,虽然我已经告诉过: class SpeakerViewModel extends ViewModelBase&lt;Speaker&gt; { ... } 我希望它成为 Speaker 的 ViewModel 我仍然有实例化 SpeakerViewModel 之类的:

let vm = new SpeakerViewModel(Speaker);

虽然我已经告诉过这一切都是关于Speaker。我想我仍然没有完全理解这一点。

【问题讨论】:

  • DataProvider.getTableData(T) 中,参数T 没有定义。
  • "我希望它成为 Speaker 的 ViewModel 我仍然有实例化 SpeakerViewModel 像:let vm = new SpeakerViewModel(Speaker);" 抱歉,我很困惑。你能改写一下吗?您要省略的代码是什么?
  • 我不确定发生了什么变化,但我只能让它与{ new(...args: any[]): T } 之类的参数签名一起使用。我怀疑这是因为我的类构造函数有参数。

标签: generics typescript


【解决方案1】:

泛型只是元数据。它们不能在调用函数时用作参数。也许你需要这样的东西:

export class ViewModelBase<T extends DataObject> {
  constructor(private Cl: {new(): T}) {
  }
  public getData(): Array<T> {
    return DataProvider.getTableData<T>(this.Cl);
  }
}

【讨论】:

  • 几乎但是你的评论让我明白了我真正需要什么:constructor(private Cl: { new(): T})...。谢谢!
  • @BroncoOostermeyer 好的。我为将来的读者修改了代码。
【解决方案2】:

也许这会有所帮助:

export abstract class BaseEntity {
  public static from<T extends BaseEntity>(c: new() => T, data: any): T {
    return Object.assign(new c(), data)
  }
  public static first<T extends BaseEntity>(c: new() => T, data) {
    if (data.rows.length > 0) {
      let item = data.rows.item(0);
      return BaseEntity.from(c, item);
    }
    return null;
  }

}

这个类可以被其他人扩展,这样你就可以在基类或其子类上调用方法。

例如:

return Product.first(Product, data);

或者:

return BaseEntity.first(Product, data);

看看如何从first()内部调用from()方法

【讨论】:

    【解决方案3】:

    定义一个基本类型并扩展它怎么样?然后你的函数可以期待基本类型,你可以用扩展类型调用它。例如:

    export interface BaseData {
      key: object
    }
    

    然后:

    import { BaseData } from 'baseDataFile'
    
    export interface DerivedData extends BaseData {
      key: someObjectType
    }
    

    现在:

    import { BaseData } from 'baseDataFile'
    
    export const someFunc = (props: BaseData) => {
        // do some stuff
        return something 
    }
    

    最后:

    import { DerivedData } from 'derivedDataFile'
    
    const myData: DerivedData = something as DerivedData
    const myNewData = someFunc(myData)
    

    【讨论】:

      猜你喜欢
      • 2019-03-05
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 2021-06-23
      • 2020-11-11
      • 1970-01-01
      相关资源
      最近更新 更多