TypeScript: 在泛型类中将泛型类型作为参数传递

14

TypeScript: 我在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);
  }
}

现在我在调用getTableData时遇到了一个“找不到名称'T'”的错误,这是我传递给它的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);
  }
}

事实上,虽然我已经在以下代码中说明了我想要它作为Speaker的ViewModel: class SpeakerViewModel extends ViewModelBase<Speaker> { ... } 但我仍需要像这样实例化SpeakerViewModellet vm = new SpeakerViewModel(Speaker); 虽然我已经告诉过它所有关于Speaker的内容。我想我还没有完全理解这个问题。

DataProvider.getTableData(T) 中,参数 T 未定义。 - Paleo
“我想让它成为一个Speaker的ViewModel,但我仍需要像这样实例化SpeakerViewModel:let vm = new SpeakerViewModel(Speaker);” 对不起,我有点困惑。您能重新表达一下吗?您想省略哪些代码? - Aluan Haddad
我不确定发生了什么变化,但我只能使用参数签名{ new(...args: any[]): T }才能使其工作。我怀疑是因为我的类构造函数有参数。 - Erik Philips
3个回答

6

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

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

1
差不多了,但是你的评论让我弄清楚了我实际需要什么:constructor(private Cl: { new(): T})...。谢谢! - Bronco Oostermeyer
1
@BroncoOostermeyer 好的,我已经编辑过了,以便于未来读者查看。 - Paleo

3
也许这会有所帮助:
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() 方法


-2
如何定义一个基础类型并进行扩展呢?这样你的函数就可以期望基础类型,并且你可以使用扩展类型来调用它。例如:
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接