【问题标题】:Typescript generic factory function including parameters for created object打字稿通用工厂函数,包括创建对象的参数
【发布时间】:2019-06-24 14:57:30
【问题描述】:

我正在尝试在 Typescript 中创建一个工厂类。工厂应设置为创建特定类的对象,包括在工厂初始化时设置的默认参数。

这是我到目前为止的想法:

type Constructor<T> = new(...args: any) => T;

class Factory<T> {
    private params: ConstructorParameters<Constructor<T>>;
    private ctor: Constructor<T>;
    init<TCtor extends Constructor<T>>(tConstructor: TCtor,
        ...params: ConstructorParameters<TCtor>)
    {
        this.ctor = tConstructor;
        this.params = params;
    }

    create(): T {
        return new this.ctor(...this.params);
    }
}

class ClassWithParams { constructor(a: number) { } }

const factory = new Factory<ClassWithParams>();
//factory.init(ClassWithParams);
// Compilation error - missing param a

factory.init(ClassWithParams, 1);
console.log(factory.create());
// instance of ClassWithParams

上面的代码运行良好(Typescript playground)。但是,它需要在施工后直接向工厂拨打init() 电话。我无法将init() 代码移动到构造函数中,因为init() 依赖泛型参数TCtor 才能正确地对参数列表进行类型检查。

我可以将 TCtor 设为类的通用参数,但这意味着每次通用引用 Factory 时都需要无缘无故地提供一个额外的类型参数。

有什么想法可以删除 init() 电话吗?

【问题讨论】:

  • 我意识到我的答案有一个错误,导致类型信息丢失。请查看更新版本
  • 哦,有趣,它似乎对我有用 - 丢失了什么类型的信息?
  • Factory.prototype.create 的返回类型错误。试试新版本
  • @AluanHaddad 新的实现不正确 - 不正确的参数没有类型错误。您的意思是 tConstructor: C 而不是 tConstructor: Constructor&lt;T&gt; 吗?

标签: typescript typescript-generics


【解决方案1】:

下面的代码有什么问题

type Constructor<T> = new (...args: any[]) => T;

class Factory<T, C extends Constructor<T> = Constructor<T>> {
    params: ConstructorParameters<C>;
    ctor: Constructor<T>;
    constructor(tConstructor: Constructor<T>,
        ...params: ConstructorParameters<C>) {
        this.ctor = tConstructor;
        this.params = params;
    }

    create(): T {
        return new (this.ctor)(...this.params)
    }
}
class ClassWithParams { constructor(a: number) { this.a = a; } a: number } 

const factory1 = new Factory(ClassWithParams);

const factory2 = new Factory(ClassWithParams, '1');

const factory3 = new Factory(ClassWithParams, 0);


const value = new Factory(ClassWithParams, 0).create().a;

正如playground 中所见,它既方便又正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2019-09-20
    • 2020-10-25
    • 2018-03-15
    • 2020-08-10
    相关资源
    最近更新 更多