Hone logo
Hone
Problems

Build a Chainable Calculator in TypeScript

Many libraries and frameworks utilize chainable methods to provide a fluent and readable API for complex operations. This challenge focuses on building a simple calculator class in TypeScript that supports chainable methods for performing arithmetic operations. Mastering this concept will equip you to design more intuitive and expressive APIs in your own TypeScript projects.

Problem Description

You are tasked with creating a ChainableCalculator class in TypeScript. This class should allow users to perform a sequence of arithmetic operations (addition, subtraction, multiplication, division) in a chainable manner. Each operation method should return this to enable chaining. The class should also maintain an internal state representing the current result of the calculations.

Key Requirements:

  1. Initialization: The calculator should be initialized with an optional starting number. If no starting number is provided, it should default to 0.
  2. Arithmetic Methods: Implement the following methods:
    • add(value: number): this: Adds value to the current result.
    • subtract(value: number): this: Subtracts value from the current result.
    • multiply(value: number): this: Multiplies the current result by value.
    • divide(value: number): this: Divides the current result by value.
  3. Chainability: All arithmetic methods must return this to allow method chaining.
  4. getResult(): number Method: Implement a method to retrieve the final calculated result.
  5. Error Handling (Division by Zero): The divide method should throw an Error if the divisor is 0.

Expected Behavior:

Users should be able to chain multiple operations together. For instance, new ChainableCalculator(10).add(5).subtract(2).multiply(3).getResult() should execute the operations sequentially and return the final result.

Edge Cases:

  • Initializing the calculator without a starting value.
  • Performing operations with zero or negative numbers.
  • Dividing by zero.

Examples

Example 1:

const calculator = new ChainableCalculator(10);
const result = calculator.add(5).subtract(2).multiply(3).getResult();
// Expected Output: 39

Explanation:

  1. Starts with 10.
  2. add(5): 10 + 5 = 15.
  3. subtract(2): 15 - 2 = 13.
  4. multiply(3): 13 * 3 = 39.
  5. getResult() returns 39.

Example 2:

const calculator = new ChainableCalculator(); // Starts with 0
const result = calculator.multiply(10).add(7).divide(2).getResult();
// Expected Output: 3.5

Explanation:

  1. Starts with 0 (default).
  2. multiply(10): 0 * 10 = 0.
  3. add(7): 0 + 7 = 7.
  4. divide(2): 7 / 2 = 3.5.
  5. getResult() returns 3.5.

Example 3 (Division by Zero):

const calculator = new ChainableCalculator(10);
try {
    calculator.divide(0);
} catch (error) {
    // Expected Output: An Error object with a message like "Cannot divide by zero."
    console.error(error.message);
}

Explanation: Attempting to divide by zero should trigger an error.

Constraints

  • All input values to arithmetic methods will be numbers.
  • The starting value (if provided) will be a number.
  • The final result should be a standard JavaScript number type.
  • Performance is not a primary concern for this challenge, but the implementation should be reasonably efficient.

Notes

  • Consider how to maintain the current state of the calculation within the class instance.
  • The this type annotation in method signatures is crucial for enabling effective TypeScript type checking of method chaining.
  • Think about how to handle the division by zero scenario gracefully by throwing an appropriate Error.
Loading editor...
typescript