import {length as en_length, area as en_area} from "enheter" import {Measure, LengthUnit, AreaUnit, } from "enheter" export type Id = string; export type Currency = "USD"; export class Price { constructor(public value : number) {} } export function price(c : Currency, value : number) { return new Price(value); } export type ProductAttributes = { name?: string, image?: string, description?: string, depth?: string, [key:string]: any, } export abstract class Product { id?: Id constructor(public pricePerUnit : Price, public attributes : ProductAttributes = {}) {} public abstract priceFor(measure : Measure<"length"> | Measure<"area">) : Price; } interface ILength { length : Measure<"length"> } interface IArea { area: Measure<"area"> } export class LengthProduct extends Product implements ILength { constructor(public pricePerUnit : Price, public length: Measure<"length">, public attributes : ProductAttributes = {}) { super(pricePerUnit, attributes); } public priceFor(length : Measure<"length">): Price { const ratio = length.convertTo(this.length.unit).divideBy(this.length).value; return { value: this.pricePerUnit.value * ratio, }; } } export class AreaProduct extends Product implements IArea { constructor(public pricePerUnit : Price, public area : Measure<"area">, public attributes : ProductAttributes = {}) { super(pricePerUnit, attributes); } public priceFor(area : Measure<"area">): Price { const ratio = area.convertTo(this.area.unit).divideBy(this.area).value; return { value: this.pricePerUnit.value * ratio, }; } }