Hone logo
Hone
Problems

Implementing Assertion Functions in TypeScript

Assertion functions are crucial for defensive programming, allowing you to explicitly state assumptions about your code's state and halt execution if those assumptions are violated. This challenge focuses on creating a suite of assertion functions in TypeScript to enhance code reliability and debugging. You'll implement functions to check for various conditions, providing clear error messages when assertions fail.

Problem Description

You are tasked with implementing a set of assertion functions in TypeScript. These functions should take a boolean expression as input and, if the expression evaluates to false, throw an error with a descriptive message. The goal is to create a robust and informative assertion system that aids in identifying and resolving bugs early in the development process.

Key Requirements:

  • assert(condition: boolean, message: string): This function should take a boolean condition and a message string. If condition is false, it should throw an error with the provided message.
  • assertType(value: any, expectedType: string, message?: string): This function should take a value, the expected type as a string (e.g., "number", "string", "boolean", "object", "array"), and an optional message. If the value's type does not match the expectedType, it should throw an error with a descriptive message. Use typeof and Array.isArray() for type checking. If no message is provided, use a default message.
  • assertPositive(value: number, message?: string): This function should take a number and an optional message. If the value is not a positive number (greater than 0), it should throw an error with a descriptive message. If no message is provided, use a default message.
  • assertNotNull(value: any, message?: string): This function should take a value and an optional message. If the value is null or undefined, it should throw an error with a descriptive message. If no message is provided, use a default message.

Expected Behavior:

  • When the assertion condition is true, the functions should do nothing and execution should continue normally.
  • When the assertion condition is false, the functions should throw an error with a clear and informative message that helps pinpoint the source of the problem.
  • The assertType function should handle the basic types "number", "string", "boolean", "object", and "array".
  • The functions should be reusable and easy to integrate into existing code.

Edge Cases to Consider:

  • Invalid input types to the assertion functions themselves (e.g., passing a non-boolean to assert). While not strictly required to handle these, consider how they might be handled gracefully.
  • Empty strings or unexpected values for the expectedType in assertType.
  • Zero as input to assertPositive.
  • Values that are both null and undefined.

Examples

Example 1:

Input: assert(true, "This should not fail");
Output: (No output - execution continues)
Explanation: The condition is true, so no error is thrown.

Example 2:

Input: assert(false, "This assertion will fail");
Output: Error: This assertion will fail
Explanation: The condition is false, so an error is thrown with the provided message.

Example 3:

Input: assertType("hello", "string", "Value is not a string");
Output: (No output - execution continues)
Explanation: The value is a string, matching the expected type.

Example 4:

Input: assertType(123, "string", "Value is not a string");
Output: Error: Value is not a string
Explanation: The value is a number, not a string, so an error is thrown.

Example 5:

Input: assertPositive(5, "Value must be positive");
Output: (No output - execution continues)
Explanation: The value is positive, so no error is thrown.

Example 6:

Input: assertPositive(0, "Value must be positive");
Output: Error: Value must be positive
Explanation: The value is not positive, so an error is thrown.

Constraints

  • The assertion functions should be implemented using standard TypeScript features.
  • Error messages should be clear and concise, providing enough information to diagnose the problem.
  • The code should be well-documented and easy to understand.
  • The assertType function should only check for the specified types ("number", "string", "boolean", "object", "array"). No need to support custom types or complex type guards.
  • Performance is not a primary concern for this challenge. Readability and correctness are prioritized.

Notes

  • Consider using throw new Error() to throw errors.
  • Think about how to make the assertion functions reusable and flexible.
  • The optional message parameter allows for more specific error messages tailored to the context of the assertion.
  • This challenge is designed to help you understand the importance of assertions in defensive programming and how to implement them effectively in TypeScript.
Loading editor...
typescript