Ch. 2 · TypeScript

TypeScript Null Narrowing Across Control Flow

TypeScript Null Narrowing Across Control Flow. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readadvancedupdated Oct 3, 2026

Strict null checking forces missing values into the contract. Narrowing follows control flow, but later mutation or callbacks may invalidate assumptions.

Before you start

You should be comfortable with JavaScript values, functions and objects. Use a TypeScript project with strict checking enabled when trying the examples. Separate what the compiler proves from what must still be checked when values arrive at runtime.

The practical goal is to reason through this situation: After checking an optional record, capture the needed stable value before scheduling delayed work. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.

Step-by-step walkthrough

Step 1: Include absence in the contract

A lookup may return undefined. Describe that possibility instead of asserting that every requested record exists.

Step 2: Narrow before reading fields

An early not-found branch removes the absent case from the continuing path. Capture stable values before delayed work if the source may change.

Step 3: Choose visible failure behavior

Return a not-found result or message. Do not let a non-null assertion turn an ordinary missing record into a property-access crash.

Worked scenario

After checking an optional record, capture the needed stable value before scheduling delayed work.

const users = [{ id: 'u1', name: 'Ada' }];
function greeting(id: string): string {
  const user = users.find(item => item.id === id);
  if (!user) return 'User not found';
  const name = user.name;
  return `Hello, ${name}`;
}
TypeScript

The early return handles absence, and the remaining branch reads a known user. Capturing name also gives later callbacks a concrete value rather than relying on a mutable lookup reference.

Common mistake

The non-null assertion silences checking without proving existence.

Verify the behavior

Request an existing and missing ID. For delayed work, mutate the owning reference after scheduling and explain whether the callback should use the captured or latest value.

Interview exercise

Handle a missing query result.

Answer and reasoning

Return an explicit not-found outcome and narrow before accessing fields; avoid asserting success for a legitimately absent record.

Continue learning

Compare the scenario with the TypeScript interview questions and test your understanding with the TypeScript MCQs. For terminology and implementation details, consult the reference material.

More in TypeScript

read ✓TypeScript · mid

TypeScript Strict Compiler Flags

Turn on strict checks, know which flags strict bundles, and layer the non-strict extras such as noUncheckedIndexedAccess.

~2 min readread →
read ✓TypeScript · hard

TypeScript Abstract Classes and Contracts

Share behavior with abstract classes, enforce required members, and decide when an interface or composition is the better contract.

~2 min readread →
esc