打字稿:如何从继承的静态属性返回子类类型?

D C*_*D C 8 static subclass typescript

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 {}
Run Code Online (Sandbox Code Playgroud)

我希望的是:当运行 SubDoc.find() 时,应用程序知道返回值的类型是 SubDoc 的实例而不是 BaseDoc。

我怎样才能做到这一点?

Tit*_*mir 12

您可以创建一个通用版本find,它将this参数推断为它被调用的类的类型,并用于InstanceType<T>从类类型中提取实际实例类型:

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
Run Code Online (Sandbox Code Playgroud)

或者您可以强制派生类定义Collection适当类型的泛型成员:

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
Run Code Online (Sandbox Code Playgroud)