Building Immutable Orders with Typescript | Task

Ole Ersoy
Mar - 14  -  2 min

Scenario

We wish to create order instances for SKU sku123 and with price $10. The only thing that will vary for each order is the quantity.

The Order class has these properties.

export class Order {
    public readonly sku;
    public readonly quantity;
    public readonly price;
    public readonly total;
  }
}

The orders will be built like this:

let builder = new OrderBuilder();
const order1 = builder.setQuantity(10).setSKU('sku123').setPrice(10).build();
const order2 = builder.setQuantity(20).setSKU('sku321').setPrice(100).build();
console.log(order1);
console.log(order2);

Approach

The full implementation for our immutable Typescript class and the corresponding builder look like this:

export class Order {
  public readonly sku;
  public readonly quantity;
  public readonly price;
  public readonly total;
  constructor(builder:OrderBuilder) {
    this.sku = builder.sku;
    this.quantity = builder.quantity;
    this.price = builder.price;
    this.total = builder.total;
  }
}

export class OrderBuilder {
  public readonly price:number;
  public readonly sku:string;
  public quantity:number;
  public total:number;
  constructor(sku:string, price:number){
    this.price = price;
    this.sku = sku;
  }
  setQuantity(quantity: number) {
    this.quantity = quantity;
    return this;
  }
  private computeTotal() {
    this.total = this.quantity*this.price;
  }
  build() {
    this.computeTotal();
    return new Order(this);
  }
}

With that implementation we can build two orders with quantities 10 and 20 like this:

let builder = new OrderBuilder('sku123', 10);
const order1 = builder.setQuantity(10).build();
const order2 = builder.setQuantity(20).build();
console.log(order1);
console.log(order2);

Flexibility

Since our builders sku and price properties are readonly we are passing these in via the builders constructor. This means we can not change these properties post builder construction, thus the design is a bit rigid.

If we want to change these properties on the fly we can remove the readonly markers and implement builder setters for sku and price . We can now change these properties on the fly as well, giving us more flexibility. Here is a demo: