具有多个构造函数的只读属性'在TypeScript中

时间:2017-04-19 11:35:45

标签: typescript

我遇到了打字稿中的一个问题,我无法找到一个优雅的解决方案......

我想使用只读属性,但它们似乎不兼容多个构造函数'。

我使用多个构造函数,因为我的对象可以直接创建,也可以从JSON存储中实例化。此外,我希望控制创建API(例如,在首次创建时创建UUID)。

我的基类看起来像:

class UserEvent {
    protected constructor(
        readonly uuid: string,
        readonly creationDate: Date,
    ) {}

    static create() {
        return new this(uuid(), new Date());
    }

    static fromJSON(jsonTree) {
        return new this(jsonTree.uuid, jsonTree.creationDate);
    }
    toJSON(): any {
        return {
            uuid: this.uuid, 
            creationDate: this.creationDate.toJSON(),
        }
    }
}

然后我想继承它并添加一些属性 -

class OrderedPizzaEvent extends UserEvent {
    private constructor(
        uuid: string,
        creationDate: Date,
        readonly pizzaFlavour: string,
        readonly pizzaSize: number,
    ) {
        super(uuid, creationDate);
    }

    static create(options: {pizzaFlavour: string, pizzaSize: number}) {
        const instance = super.create();
        instance.pizzaFlavour = options.pizzaFlavour;
        instance.pizzaSize = options.pizzaSize;
        return instance;
    }

    static fromJSON(jsonTree) {
        const instance = super.fromJSON(jsonTree);
        instance.pizzaFlavour = jsonTree.pizzaFlavour;
        instance.pizzaSize = jsonTree.pizzaSize;
        return instance;
    }
    toJSON() {
        const result = super.toJSON();
        result.pizzaFlavour = this.pizzaFlavour;
        result.pizzaSize = this.pizzaSize;
        return result;
    }
}

这不起作用,因为readonly属性未设置构造函数。但是,在使用create()fromJSON()的超级实现时,我无法使用正确的参数调用构造函数。

还有另一种方法可以实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

这很有效,但它不是很漂亮/干净:

class UserEvent {
    protected constructor(
        readonly uuid: string,
        readonly creationDate: Date,
    ) {}

    static create() {
        return new this("KEY", new Date());
    }

    static fromJSON(jsonTree) {
        return new this(jsonTree.uuid, jsonTree.creationDate);
    }
    toJSON(): any {
        return {
            uuid: this.uuid, 
            creationDate: this.creationDate.toJSON(),
        }
    }
}

class OrderedPizzaEvent extends UserEvent {
    private constructor(
        uuid: string,
        creationDate: Date,
        readonly pizzaFlavour: string,
        readonly pizzaSize: number,
    ) {
        super(uuid, creationDate);
    }

    static createOrderedPizzaEvent(options: { pizzaFlavour: string, pizzaSize: number }) {
        return this.createInstance(super.create(), options);
    }

    private static createInstance(temp: UserEvent, options: { pizzaFlavour: string, pizzaSize: number }) {
        return new this(temp.uuid,
            temp.creationDate,
            options.pizzaFlavour,
            options.pizzaSize);
    }

    static fromJSON(jsonTree) {
        const instance = super.fromJSON(jsonTree) as OrderedPizzaEvent;
        return this.createInstance(instance, instance);
    }

    toJSON() {
        const result = super.toJSON();
        result.pizzaFlavour = this.pizzaFlavour;
        result.pizzaSize = this.pizzaSize;
        return result;
    }
}