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:
x is T): returns a boolean, narrowing happens in an if blockasserts x is T): void return, narrowing happens after the callfunction assertDefined<T>(
val: T | null | undefined,
message?: string,
): asserts val is NonNullable<T>Error with message if val is null or undefinedmessage provided, use a descriptive defaultvoid on success (TypeScript infers the narrowing)Note: NonNullable<T> is a built-in utility type that removes null | undefined from T.
Sample tests