TypeScript Null Safety

A quick reference for handling null and undefined with optional chaining, coalescing, and strict guards.

TL;DR

  1. Navigate nested properties safely using optional chaining ?. operators.
  2. Provide fallback defaults for nullish values with double question ?? marks.
  3. Eliminate null and undefined using strict equality guard checks.

Optional Chaining

    property chaining

    Short-circuits to undefined if target object is nullish.

    type User = { profile?: { name: string } };
    function getName(u?: User) {
      return u?.profile?.name;
    }
    method chaining

    Invokes optional methods only if they exist on the object.

    type Worker = { stop?: () => void };
    function halt(w?: Worker) {
      w?.stop?.();
    }
    element indexing

    Safely accesses array elements or dynamic dictionary keys.

    function getFirstTag(tags?: string[]) {
      return tags?.[0];
    }

Nullish Coalescing

    ?? operator

    Supplies fallback defaults only for null or undefined.

    const input: string | null = null;
    const text = input ?? 'Default text';
    preserving zero

    Retains numeric zeros without triggering fallback defaults.

    function setLimit(max?: number) {
      return max ?? 50; // preserves 0
    }
    chained defaults

    Cascades multiple fallback lookups in order of priority.

    const host = envHost ?? configHost ?? 'localhost';

Type Guards for Null

    strict equality guard

    Narrows nullable types by checking inequality with null.

    function printLength(str: string | null) {
      if (str !== null) {
        console.log(str.length);
      }
    }
    truthiness narrowing

    Discards nullish states along with other falsy values.

    function display(val?: string) {
      if (val) {
        console.log(val.toUpperCase());
      }
    }
    NonNullable helper

    Strips null and undefined from an existing union type.

    type Raw = string | number | null | undefined;
    type Clean = NonNullable<Raw>; // string | number

Optional vs Nullable

    optional property

    Allows omitting property from object structure entirely.

    interface Config {
      port?: number; // number | undefined
    }
    explicit null union

    Requires key presence while permitting an intentional null value.

    interface Record {
      id: string;
      deletedAt: Date | null;
    }
    exactOptionalPropertyTypes

    Distinguishes omitted keys from keys assigned undefined.

    interface Props {
      color?: string;
    }
    // Under exactOptional, { color: undefined } is invalid

Non-Null Assertion

    ! assertion operator

    Forces compiler to treat a nullable expression as non-null.

    const el = document.getElementById('app')!;
    el.textContent = 'Hello World';
    definite assignment

    Informs compiler that property is initialized out-of-line.

    class Server {
      address!: string;
      init() { this.address = '0.0.0.0'; }
    }
    runtime guard alternative

    Replaces dangerous assertions with explicit error checks.

    function requireValue<T>(val: T | null): T {
      if (val === null) throw new Error('Null value');
      return val;
    }

Tips

  1. Always enable strictNullChecks in your tsconfig.json to prevent silent null dereferencing errors across your entire codebase.
  2. Prefer the nullish coalescing ?? operator over logical OR || when zero or empty strings represent valid input values.

Warnings

  1. Avoid the non-null assertion ! operator because it suppresses compiler warnings without providing any runtime validation.
  2. Remember that Array.find() returns undefined when no match exists, requiring explicit nullish checks before property access.

In Practice

FAQ