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. Ifconditionisfalse, it should throw an error with the providedmessage.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 theexpectedType, it should throw an error with a descriptive message. UsetypeofandArray.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 isnullorundefined, 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
assertTypefunction 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
expectedTypeinassertType. - Zero as input to
assertPositive. - Values that are both
nullandundefined.
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
assertTypefunction 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.