【发布时间】:2018-09-26 12:47:31
【问题描述】:
以下错误
静态成员不能引用类类型参数。
以下代码的结果
abstract class Resource<T> {
/* static methods */
public static list: T[] = [];
public async static fetch(): Promise<T[]> {
this.list = await service.get();
return this.list;
}
/* instance methods */
public save(): Promise<T> {
return service.post(this);
}
}
class Model extends Resource<Model> {
}
/* this is what I would like, but the because is not allowed because :
"Static members cannot reference class type parameters."
*/
const modelList = await Model.fetch() // inferred type would be Model[]
const availableInstances = Model.list // inferred type would be Model[]
const savedInstance = modelInstance.save() // inferred type would be Model
我认为从这个例子中可以清楚地看到我想要实现的目标。我希望能够在我的继承类上调用实例和静态方法,并将继承类本身作为推断类型。我找到了以下解决方法来获得我想要的:
interface Instantiable<T> {
new (...args: any[]): T;
}
interface ResourceType<T> extends Instantiable<T> {
list<U extends Resource>(this: ResourceType<U>): U[];
fetch<U extends Resource>(this: ResourceType<U>): Promise<U[]>;
}
const instanceLists: any = {} // some object that stores list with constructor.name as key
abstract class Resource {
/* static methods */
public static list<T extends Resource>(this: ResourceType<T>): T[] {
const constructorName = this.name;
return instanceLists[constructorName] // abusing any here, but it works :(
}
public async static fetch<T extends Resource>(this: ResourceType<T>): Promise<T[]> {
const result = await service.get()
store(result, instanceLists) // some fn that puts it in instanceLists
return result;
}
/* instance methods */
public save(): Promise<this> {
return service.post(this);
}
}
class Model extends Resource {
}
/* now inferred types are correct */
const modelList = await Model.fetch()
const availableInstances = Model.list
const savedInstance = modelInstance.save()
我遇到的问题是覆盖静态方法变得非常乏味。执行以下操作:
class Model extends Resource {
public async static fetch(): Promise<Model[]> {
return super.fetch();
}
}
将导致错误,因为Model 不再正确扩展Resource,因为签名不同。我想不出一种方法来声明一个 fetch 方法而不给我错误,更不用说有一种直观简单的重载方法了。
我可以开始工作的唯一解决方法是:
class Model extends Resource {
public async static get(): Promise<Model[]> {
return super.fetch({ url: 'custom-url?query=params' }) as Promise<Model[]>;
}
}
在我看来,这不是很好。
有没有一种方法可以覆盖 fetch 方法,而不必手动转换为 Model 并使用泛型进行技巧?
【问题讨论】:
标签: javascript typescript generics inheritance