class Expression { private static readonly INVALID_REQUEST: string = "400: Bad request"; value: string; l: Expression | null = null; r: Expression | null = null; private splitBy(operation: string): boolean { let splitOperands = this.value.split(operation); if (splitOperands.length < 2) { return false; } this.value = operation; this.r = new Expression(splitOperands.pop()); this.l = new Expression(splitOperands.join(operation)); return true; } constructor(expr: string) { this.value = expr; for (let operation of "+-*$") { if (this.splitBy(operation)) { return; } } } public evaluate(): (number | string) { if (this.l === null && this.r === null) { // process constants if (![...this.value].every(c => "0123456789.".includes(c))) { return Expression.INVALID_REQUEST; } const val = Number.parseFloat(this.value); return val; } if (this.l === null || this.r === null || !("+-$*".includes(this.value))) { return Expression.INVALID_REQUEST; } const left = this.l.evaluate(); const right = this.r.evaluate(); if (typeof left !== "number" || typeof right !== "number") { return Expression.INVALID_REQUEST; } let operation = null; switch (this.value) { case "+": return left + right; case "-": return left - right; case "$": return left / right; case "*": return left * right; } } } export const calculate = (sum: string): (number | string) => { return new Expression(sum).evaluate(); }