【问题标题】:Typescript - infer constructor args to static factory method in parent classTypescript - 将构造函数参数推断为父类中的静态工厂方法
【发布时间】:2021-10-22 16:41:50
【问题描述】:

我有一个名为Entity 的基类和一个扩展Entity 的子类DebugEntity。从Entity 派生的子类可以有自己的带有任意参数的构造函数。我希望将这些参数输入到 Entity 类中的静态 make 方法中。

经过多次尝试/错误,我走到了这一步:

class DebugEntity extends Entity
{
    public constructor(name: string, age: number)
    {
        console.log({name, age});
    }

    public testMe(): void
    {
        console.log('Hello from DebugEntity')
    }

}
export abstract class Entity
{
    public static async make<T extends Entity, K extends new (...args: any[]) => T>(
        this: K,
        ...args: K extends new (...args: infer U) => T ? U : never
    ): Promise<T>
    {
        const entity     = new this(...args);
        
        // Do some async stuff (unrelated to question)

        return entity;
    }
}

Typescript 正确推断构造函数参数。例如:DebugEntity.make() 现在需要两个参数 [string, number]。但是,Typescript 认为 make 的返回类型是 Entity 而不是 DebugEntity

在构造的实体上调用testMe会产生以下结果:

Property 'testMe' does not exist on type 'Entity'.

我可以通过将 this: 参数修改为 this: new (...args: any[]) =&gt; T 轻松解决此问题,但由于某种原因,这会破坏参数类型推断。

我应该如何解决这个问题?

提前致谢!

【问题讨论】:

    标签: typescript generics


    【解决方案1】:

    好的,我在发布后立即进行了一些更时髦的试验和错误,显然这是可行的:

        public static async make<T extends Entity, K extends new (...args: any[]) => InstanceType<K>>(
            this: K,
            ...args: K extends new (...args: infer U) => T ? U : never
        ): Promise<InstanceType<K>>
        {
            const entity     = new this(...args);
    
            // do async stuff.
    
            return entity;
        }
    

    使用内置的InstanceType 类型就可以了。 不过,我不确定是否有任何不需要的副作用......

    【讨论】:

    • 这是一个非常好的解决方案!我尝试使用InstanceType&lt;typeof this&gt;,但出乎意料地不起作用。似乎起作用的重要部分是您使用第一个参数this: Ktypeof this 并没有达到同样的结果,这真的很奇怪。
    • 为了提供更多背景信息,我试图调用父类',比如来自子类的Parent 静态方法,比如Child.parentStaticMethod(),但是当使用typeof this 时,Typescript 总是认为this 绑定的类型为 typeof Parent。现在我添加了this: K 的第一个伪参数,Typescript 正确地将this 类型推断为typeof Child
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-18
    • 2014-07-13
    相关资源
    最近更新 更多