Type Guard for Non-Null Values
TypeScript type guard to filter out null/undefined values from arrays
Implementation
Copy the complete example or adapt its typed interface to your project. Comments are kept inside the snippet so the intent travels with the code.
/**
* Type guard to check if value is not null/undefined
* @param value Value to check
* @returns Type predicate confirming non-null/undefined
*/
function isNotNullOrUndefined<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
// Usage Example
const mixedArray = [1, null, 2, undefined, 3, 4, null];
const filteredArray = mixedArray.filter(isNotNullOrUndefined);
// filteredArray type is number[] (not (number | null | undefined)[])
console.log(filteredArray); // [1, 2, 3, 4]
// With objects
interface User {
id: number;
name?: string | null;
}
const users: User[] = [{ id: 1, name: 'John' }, { id: 2, name: null }, { id: 3 }];
const usersWithNames = users
.map(user => user.name)
.filter(isNotNullOrUndefined);
// usersWithNames type is string[]When to use it
Essential for TypeScript projects to maintain type safety when filtering null/undefined values from arrays
Review the input assumptions and browser or runtime support before adopting a utility unchanged. Small helpers are easiest to maintain when their contract stays narrow.
Reasoning and trade-offs
How it works
The predicate removes null and undefined from a union type while returning true for all other values. TypeScript recognizes the type-predicate signature, so filter produces an array whose element type no longer includes nullish members.
What to watch for
Truthiness filters also remove valid zero, false, and empty-string values, which is why an explicit nullish comparison matters. The guard proves only presence; it does not validate the remaining value’s deeper shape.
Production use
Use this named guard after optional mapping, sparse lookups, or partial API results. Pair it with a schema or property guard when external data also needs runtime validation beyond null and undefined.
Before you ship
- Confirm the input contract with tests that cover empty, invalid, boundary, and representative real-world values before sharing the helper across a codebase.
- Keep the function focused on one responsibility and name any project-specific policy explicitly instead of hiding it inside a generic-looking utility.
- Measure behavior in the browsers or runtime versions your product supports, especially when timing, storage, DOM state, locale, or network access is involved.
- Document the return type, mutation behavior, failure mode, and performance characteristics beside the call site so future maintainers can evaluate changes safely.
- Compare the example with current official platform documentation when it relies on a browser API, language feature, or runtime behavior that may change over time.
- If the helper crosses a trust boundary, validate again on the server and avoid treating browser-side checks, TypeScript annotations, or formatted output as a security guarantee.
- Add a small regression test whenever a real edge case is discovered; concrete examples preserve the reason behind a guard more reliably than a general comment.