EasyJavaScriptTypeScript

Assertion Functions (asserts val is T)

TypeScriptTypes

TypeScript supports a special kind of function that asserts a condition. If the function returns without throwing, TypeScript narrows the type:

function assertDefined<T>(
  val: T | null | undefined,
): asserts val is NonNullable<T> {
  if (val == null) throw new Error('Value is null or undefined');
}

let config: Config | null = loadConfig();
assertDefined(config);
config.apiKey; // TypeScript knows config is Config here ✅

The key difference from a type guard:

  • Type guard (x is T): returns a boolean, narrowing happens in an if block
  • Assertion function (asserts x is T): void return, narrowing happens after the call

Implement

function assertDefined<T>(
  val: T | null | undefined,
  message?: string,
): asserts val is NonNullable<T>
  • Throws Error with message if val is null or undefined
  • If no message provided, use a descriptive default
  • Returns void on success (TypeScript infers the narrowing)

Note: NonNullable<T> is a built-in utility type that removes null | undefined from T.

Sample tests

Test #1number passes assertion
Input: [42]
Output: {"value":42,"thrown":false}
Test #2string passes assertion
Input: ["hello"]
Output: {"value":"hello","thrown":false}
Test #3null throws
Input: [null]
Output: {"thrown":true,"message":"Expected defined value, got null"}
Test #4custom message is used
Input: [null,"User is required"]
Output: {"thrown":true,"message":"User is required"}
Test #50 is defined (falsy but not null)
Input: [0]
Output: {"value":0,"thrown":false}