2017-04-19 79 views
0

我反對打字稿的問題,我無法找到一個優雅的解決跑起來多「建設者」 ......只讀屬性與打字稿

我想用只讀屬性,但他們不」 t似乎與多個「構造函數」兼容。

我使用多個構造函數,因爲我的對象可以直接創建,或從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; 
    } 
} 

這不起作用,因爲只讀屬性未設置構造函數。但是在使用超級實現create()fromJSON()時,我無法使用正確的參數調用構造函數。

是否有另一種方法來實現這一目標?

回答

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; 
    } 
}