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
TypeScript: pass generic type as parameter in generic class
提问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 Speaker
I still have the instantiate the SpeakerViewModel
like:
问题是,虽然我已经告诉过:
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)