logo hsb.horse
← Back to snippets index

Snippets

TypeScript Non-null Assertion

TypeScript type guard functions to eliminate undefined and null. Ensures both runtime errors and type safety.

Published: Updated:

When accessing external APIs or array indices, values may become undefined, making them difficult to handle as-is in terms of type. Use non-null assertions to achieve both runtime checks and type narrowing.

Code

function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error(`Expected 'value' to be defined, but received ${value}`);
}
}
function nonNull<T>(value: T): NonNullable<T> {
assertIsDefined(value);
return value;
}

Usage Examples

Safe Array Element Access

const arr = [1, 2, 3];
const value = arr[10]; // number | undefined
// Cannot avoid type error
console.log(value.toFixed()); // Error: Object is possibly 'undefined'
// Using nonNull
const safeValue = nonNull(arr[10]);
// Inferred as NonNullable<number>
console.log(safeValue.toFixed()); // OK

API Response Validation

interface User {
name: string;
}
async function getUser(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
const user = await response.json() as User | undefined;
// Error if response is empty
assertIsDefined(user);
// user can be treated as User type at this point
return user;
}

Difference from the ! Operator

TypeScript has a non-null assertion operator value!, but this does not perform runtime checks. Using assertion functions allows you to validate values at runtime while also narrowing the type.

Cautions

Use assertion functions only when you are confident that a value truly exists. Careless use will result in runtime errors. Especially for array index access, consider checking length beforehand.