【问题标题】:Typescript: how to return subclass type from inherited static property?Typescript:如何从继承的静态属性返回子类类型?
【发布时间】:2018-08-15 21:42:50
【问题描述】:
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。

我怎样才能做到这一点?

【问题讨论】:

    标签: typescript static subclass


    【解决方案1】:

    您可以创建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
    

    或者您可以强制派生类定义适当类型的通用 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
    

    【讨论】:

    • 太棒了!它摇滚!
    • 当SubDoc有constructor(public prop)时会报错:[ts] The 'this' context of type 'typeof SubDoc' is not assignable to method'this' type of 'typeof DocBase '。
    • @DC 抱歉,我花了一段时间才回来,我正在让孩子上床睡觉 :)。您可以在我的第二个示例中使用该方法,不幸的是,typeof BasDoc 将要求一个空的构造函数。这应该工作static find&lt;T extends { new (... args: any[]) : BaseDoc, Collection: any }&gt;(this: T): InstanceType&lt;T&gt;
    • 非常感谢!它再次起作用!顺便说一句,我更喜欢你的第一个例子,因为它很简单。
    • @Dylan BaseDoc 是实例类型,typeof BaseDoc 是类类型。当您调用实例方法时,这是该类型的实例,因此 this 将与实例类型具有相同的类型。当您调用静态方法时,this 将是类本身(因为这是调用该方法的对象),因此 this 将扩展为 typeof BaseDoc
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    相关资源
    最近更新 更多