interface Measurement { getText : () => string; } /** * A measure is ALWAYS created in Centimeters. * How a measure gets displayed can get changed later, so always use this class for measures! * If you're american, use the helper static functions fromInches, fromFeet to get centimeters. * For instance, 5'10" would get created as: * new Measure(Measure.fromFeet(5) + Measure.fromInches(10) * * If multiple measurements are added, it's treated as area of something simple like rectangles or cubes or whatever, they're just multiplied. */ class Measure implements Measurement { private units : number; private sides : number; public constructor (...sides : Array) { this.units = 1; sides.forEach((side) => { this.units *= side; }); this.sides = sides.length; } // ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] private superscript = ["" , "" , "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]; public getText () { let meters = Math.pow(this.sides, 100); if (this.units > meters) { return (+(this.units / meters).toFixed(2)).toString() + "m" + this.superscript[this.sides]; } else { return this.units.toString() + "cm" + this.superscript[this.sides]; } } public getNumber () { return this.units; } public getSides () { return this.sides; } public static fromInches (inches : number) { return inches * 2.54; } public static fromFeet (feet : number) { return feet * 30.48; } } class MeasureLiquid implements Measurement { private units : number; public constructor (milliliters : number) { this.units = milliliters; } public getText () { if (this.units > 1000) { return (+(this.units / 1000).toFixed(2)).toString() + "L"; } else { return this.units.toString() + "mL"; } } public static fromLiters (liters : number) { return liters * 1000; } }