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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37482342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:31:52  来源:igfitidea点击:

TypeScript: pass generic type as parameter in generic class

genericstypescript

提问by Bronco Oostermeyer

TypeScript:I have a method in the DataProvider class with a method getTableData:

TypeScript:我在 DataProvider 类中有一个方法,其中有一个方法 getTableData:

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

this works perfectly when I code:

当我编码时,这非常有效:

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

now I want to call this from a generic Class:

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

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

Now I get a Cannot find name 'T'error for the T parameter I pass to getTableData. How should getTableData be called?

现在,对于传递给 getTableData 的 T 参数,出现无法找到名称“T”的错误。应该如何调用 getTableData?

update: With the help of @Paleo I came up this:

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

export class ViewModelBase<T extends DataObject> {   

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

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

the thing is that although I have already told in: class SpeakerViewModel extends ViewModelBase<Speaker> { ... }that I want it to be a ViewModel for SpeakerI still have the instantiate the SpeakerViewModellike:

问题是,虽然我已经告诉过: class SpeakerViewModel extends ViewModelBase<Speaker> { ... }我希望它是一个 ViewModel 因为Speaker我仍然有这样的实例化SpeakerViewModel

let vm = new SpeakerViewModel(Speaker);

let vm = new SpeakerViewModel(Speaker);

although I have already told it is all about Speaker. I guess I still don't fully understand this.

虽然我已经说过了Speaker。我想我仍然没有完全理解这一点。

回答by Paleo

Generics are just metadata. They cannot be used as parameters when calling a function. Maybe you need something like this:

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

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

回答by flags

maybe this would help:

也许这会有所帮助:

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

}

This class can be extended by others so you could call methods on the base class or on its subclasses.

此类可以由其他人扩展,因此您可以在基类或其子类上调用方法。

For instance:

例如:

return Product.first(Product, data);

Or:

或者:

return BaseEntity.first(Product, data);

See how from()method is called from inside first()

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

回答by glowkeeper

How about defining a base type and extending it? Then your function could expect the base type, and you could call it with the extended type. e.g:

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

export interface BaseData {
  key: object
}

Then:

然后:

import { BaseData } from 'baseDataFile'

export interface DerivedData extends BaseData {
  key: someObjectType
}

Now:

现在:

import { BaseData } from 'baseDataFile'

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

Finally:

最后:

import { DerivedData } from 'derivedDataFile'

const myData: DerivedData = something as DerivedData
const myNewData = someFunc(myData)