Hone logo
Hone
Problems

Implementing a Non-Nullable Helper Function in TypeScript

TypeScript's type system is powerful, but sometimes you need a concise way to ensure a value is not null or undefined. This challenge asks you to implement a helper function that takes a value and returns a non-nullable version of it, effectively asserting that the value is not null or undefined. This is useful for simplifying code and improving type safety when dealing with potentially nullable values.

Problem Description

You need to create a TypeScript function called nonNullable that accepts a value of any type T and returns a value of type NonNullable<T>. The NonNullable<T> utility type in TypeScript removes null and undefined from the union of types that T can be. Your function should effectively replicate this behavior.

Key Requirements:

  • The function must be type-safe. It should correctly infer the non-nullable type based on the input.
  • The function should return the original value if it is already non-nullable.
  • The function should throw a TypeError if the input is null or undefined. This is to explicitly signal that the input was not a valid value for the intended operation.

Expected Behavior:

  • If the input is null or undefined, the function should throw a TypeError with a descriptive message.
  • If the input is a non-nullable value (e.g., a string, number, object, or a type that explicitly excludes null and undefined), the function should return the input value unchanged.
  • The function should preserve the type information of the non-nullable value.

Edge Cases to Consider:

  • Input of null
  • Input of undefined
  • Input of a primitive type (string, number, boolean)
  • Input of an object
  • Input of a union type that includes null or undefined (e.g., string | null)

Examples

Example 1:

Input: nonNullable(null)
Output: TypeError: Input cannot be null or undefined.
Explanation: The input is null, so a TypeError is thrown.

Example 2:

Input: nonNullable(undefined)
Output: TypeError: Input cannot be null or undefined.
Explanation: The input is undefined, so a TypeError is thrown.

Example 3:

Input: nonNullable("hello")
Output: "hello"
Explanation: The input is a non-nullable string, so it's returned unchanged.

Example 4:

Input: nonNullable(123)
Output: 123
Explanation: The input is a non-nullable number, so it's returned unchanged.

Example 5:

Input: nonNullable({ name: "John" })
Output: { name: "John" }
Explanation: The input is a non-nullable object, so it's returned unchanged.

Example 6:

Input: nonNullable<string | null>("world")
Output: "world"
Explanation: The input is a string, which is non-nullable, so it's returned unchanged.

Example 7:

Input: nonNullable<string | null>(null)
Output: TypeError: Input cannot be null or undefined.
Explanation: The input is null, so a TypeError is thrown.

Constraints

  • The function must be written in TypeScript.
  • The function must throw a TypeError when the input is null or undefined.
  • The function should handle any valid TypeScript type as input.
  • The function should not introduce any unnecessary dependencies.
  • The function should be relatively performant (avoiding complex or inefficient operations).

Notes

Consider using TypeScript's conditional types to achieve the desired type narrowing. Think about how to handle the case where the input is already non-nullable without throwing an error. The goal is to create a robust and type-safe helper function that can be used throughout your TypeScript projects.

Loading editor...
typescript