Class Typescript返回基类中工厂方法的类型
我来自Python背景,在尝试使用以下继承模型使Typescript满意时遇到了一些问题 给定以下基类:Class Typescript返回基类中工厂方法的类型,class,typescript,oop,inheritance,Class,Typescript,Oop,Inheritance,我来自Python背景,在尝试使用以下继承模型使Typescript满意时遇到了一些问题 给定以下基类: // model.ts export class Model { serialize() {} static deserialize(dbRow) {} static async filter(options) { const dbRows = await getData(options); return dbRows.map(r
// model.ts
export class Model {
serialize() {}
static deserialize(dbRow) {}
static async filter(options) {
const dbRows = await getData(options);
return dbRows.map(row => this.deserialize(row));
}
}
下面的类扩展了它:
// user.ts
export class User extends Model {
serialize() {......}
static deserialize(dbRow) {......return new User(......)}
someOtherMethod() {.....}
}
如何定义Model.filter,以便const users=wait User.filter({….})
将自动推断用户类型为User[]?现在,推断的类型是Model[]
我知道我可以做
const users=await User.filter({….})
,但我想知道是否有任何方法可以建议Model.filter的返回类型作为类构造函数,以便正确推断子类的实例。您可以将Model
设置为泛型:
// model.ts
export class Model<T> {
...
static async filter(options): Array<T> {
const dbRows = await getData(options);
return dbRows.map(row => this.deserialize(row));
}
}
//model.ts
导出类模型{
...
静态异步筛选器(选项):数组{
const dbRows=等待获取数据(选项);
返回dbRows.map(row=>this.deserialize(row));
}
}
然后:
// user.ts
export class User extends Model<User> {
...
}
//user.ts
导出类用户扩展模型{
...
}
您可以阅读有关Typescript泛型的更多信息。您可以使用以下解决方法(在中多次提到):
type modelcontuctor=new()=>T;
类模型{
// ...
静态异步过滤器(这个:modelcontuctor&typeof模型,选项):Promise{
const dbRows=等待获取数据(选项);
返回dbRows.map(row=>this.deserialize(row));
}
}
这里我们使用伪
这个
参数,当调用User.filter
时,它强制将T
解析为User
。来自Typescript的文档:“泛型类仅在其实例端而不是静态端是泛型的,因此在处理类时,静态成员不能使用类的类型参数。”好的,我假设这是一个存储库模式(OOP)filter
是一个实例方法。我知道为什么反序列化
是一个静态方法,但不知道为什么filter必须是静态的。谢谢!你链接的线程确实帮助我了解了其他人正在做什么来解决这个问题。现在我将继续使用类型提示,因为我从该线程尝试的解决方案也迫使我定义ineModel.以类似的方式反序列化
。如果反序列化
在子类中没有实现,这不会太痛苦,但这正是将要发生的事情。对此类的所有用户强制这样做似乎有点苛刻。为什么需要以类似的方式定义Model.反序列化
?对我来说就是这样
type ModelContructor<T> = new () => T;
class Model {
// ...
static async filter<T extends Model>(this: ModelContructor<T> & typeof Model, options): Promise<T[]> {
const dbRows = await getData(options);
return dbRows.map(row => this.deserialize(row));
}
}