繁体   English   中英

打字稿:包装函数返回泛型类的类型

[英]Typescript: Wrap function return type of generic class

我无法使用 Typescript 以通用方式解决这个问题,我将不胜感激!

  • 工厂应该部署合同
  • CustomFactory 是一个工厂,应该部署一个 CustomContract(即一个 Contract)
  • MockFactory 应该是所有这些逻辑的包装器

像这样的东西将是目标(半伪代码)

interface MockFactory<F extends Factory> extends F {
    deploy: (...args: Parameters<F.prototype.deploy>) => MockContract<F.prototype.deploy.returnValue>
}

为了更好地说明问题,我创建了一个Playground ,您可以在其中看到错误

刚刚通过使用 ReturnType 和 Parameters 解决了,以及将接口转换为类型所需的:

更新的游乐场

您可以使用(抽象)类,但接口也是可能的。 在这种情况下,使工厂本身通用似乎是错误的举动。 改为使合同类型通用。 经过一番玩耍后,我能够将其拼凑在一起:

interface Contract { }

interface Factory<A extends any[], C extends Contract> {
    deploy: (...args: A) => C;
}

// Some helper types
type FactoryArgs<F extends Factory<any, any>> = F extends Factory<infer A, any> ? A : never;
type FactoryContractType<F extends Factory<any, any>> = F extends Factory<any, infer C> ? C : never;

interface FactoryForClass<C extends new (...args: any) => Contract> {
    //deploy: C extends new (...args: infer A) => infer T ? Factory<A, T>['deploy'] : never;
    deploy: Factory<ConstructorParameters<C>, InstanceType<C>>['deploy'];
}

class CustomContract implements Contract {
    constructor(a: number, b: number) { }
}

class CustomFactory implements FactoryForClass<typeof CustomContract> {
    deploy(x: number, y: number): CustomContract {
        return new CustomContract(x, y);
    }
}

type MockContract<C extends Contract> = Contract & C & {
    mockProperty: number;
}

type MockFactory<F extends Factory<any, any>> = F & {
    deploy: (...args: FactoryArgs<F>) => MockContract<FactoryContractType<F>>;
}

const mockFactory: MockFactory<CustomFactory> = {
    deploy(a: number, b: number) {
        const customContract = new CustomContract(a, b);
        const result: CustomContract & MockContract<CustomContract> = customContract as any;
        result.mockProperty = 123;
        return result;
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM