打字稿:如何从继承的静态属性返回子类类型?
问题描述:
class BaseDoc {
static Collection;
static find(){
// which is expected to return an instance of SubDoc when run SubDoc.find()
return this.Collection.find();
}
}
class SubDoc extends BaseDoc {}
我希望的是:当运行 SubDoc.find() 时,应用程序知道返回值的类型是 SubDoc 的实例而不是 BaseDoc.
What I hope is: When running SubDoc.find(), the app knows the type of the return value to be an instance of SubDoc rather than BaseDoc.
我怎样才能做到这一点?
How can I achieve that?
答
您可以创建 find
的通用版本,该版本会将 this
参数推断为调用它的类,并使用 InstanceType
从类类型中提取实际实例类型:
You can create a generic version of find
that will have the this
parameter inferred to the type of the class it's being called on, and use InstanceType<T>
to extract the actual instance type from the class type:
class BaseDoc {
static Collection: any;
static find<T extends typeof BaseDoc>(this: T): InstanceType<T> {
// which is expected to return an instance of SubDoc when run SubDoc.find()
return this.Collection.find();
}
}
class SubDoc extends BaseDoc {
}
SubDoc.find() // return SubDoc
或者您可以强制派生类定义适当类型的通用Collection
成员:
Or you can mandate that the derived class defines a generic Collection
member of the appropriate type:
class Collection<T> {
find(): T {
return null as any // dummy imeplmentation
}
}
type GetCollectionItem<T extends Collection<any>> = T extends Collection<infer U> ? U: never;
class BaseDoc {
static Collection: Collection<BaseDoc>;
static find<T extends { new (... args: any[]) : any, Collection: Collection<any> }>(this: T): GetCollectionItem<T['Collection']> {
// which is expected to return an instance of SubDoc when run SubDoc.find()
return this.Collection.find();
}
}
class SubDoc extends BaseDoc {
static Collection: Collection<SubDoc>;
}
SubDoc.find() // return SubDoc