Hone logo
Hone
Problems

Strict Null Check Helpers in TypeScript

TypeScript's strict null checks are a powerful tool for preventing unexpected null or undefined errors. However, sometimes you need more control over how you handle these values, especially when dealing with legacy code or complex data structures. This challenge asks you to create reusable helper functions that provide strict null checks with customizable behavior, enhancing code clarity and robustness.

Problem Description

You are tasked with creating two TypeScript helper functions: assertNotNull and assertDefined. These functions will take a value as input and perform a strict null check. If the value is null or undefined, they should throw a specific error. The functions should be generic, allowing them to work with any type. The error message should be customizable, providing context about where the null check failed.

Key Requirements:

  • Generics: The functions must be generic to handle any data type.
  • Strict Null Check: The functions must explicitly check for both null and undefined.
  • Error Throwing: If the input is null or undefined, the function must throw an Error.
  • Customizable Error Message: The functions should accept an optional error message string that will be included in the thrown Error.
  • Clear Error Type: The thrown error should be a standard Error object.

Expected Behavior:

  • If the input value is not null or undefined, the function should return the value unchanged.
  • If the input value is null or undefined, the function should throw an Error with the provided (or default) error message.

Edge Cases to Consider:

  • What happens if the error message is an empty string?
  • How should the functions behave with primitive types (e.g., numbers, strings, booleans)?
  • Consider the potential for unexpected behavior if the input is a value that coerces to null or undefined (though strict checks should prevent this).

Examples

Example 1:

Input: assertNotNull<string>("hello", "Value cannot be null or undefined");
Output: "hello"
Explanation: The input is a valid string, so the function returns it unchanged.

Example 2:

Input: assertNotNull<number>(null, "Value cannot be null or undefined");
Output: Throws Error: "Value cannot be null or undefined"
Explanation: The input is null, so the function throws an error with the provided message.

Example 3:

Input: assertNotNull<boolean>(undefined, "Value is required");
Output: Throws Error: "Value is required"
Explanation: The input is undefined, so the function throws an error with the provided message.

Example 4:

Input: assertDefined<number>(5)
Output: 5
Explanation: The input is a number, so the function returns it unchanged.

Example 5:

Input: assertDefined<string>(null)
Output: Throws Error: "Value cannot be null or undefined" (default message)
Explanation: The input is null, so the function throws an error with the default message.

Constraints

  • The functions must be written in TypeScript.
  • The error message string should be limited to a maximum length of 255 characters. (This is a practical consideration for database logging or UI display).
  • The functions should be performant; avoid unnecessary operations. Simple checks are preferred.
  • The functions should be easily understandable and maintainable.

Notes

  • Consider using TypeScript's type guards to enhance type safety.
  • Think about how to provide a sensible default error message when one is not explicitly provided.
  • The assertDefined function should behave identically to assertNotNull in this challenge. The purpose of this function is to demonstrate the ability to create similar helpers with slightly different names or default behaviors in a real-world scenario.
  • Focus on clarity and correctness over extreme optimization.
Loading editor...
typescript