LLearnCode
Academy/typescript/Contracts that survive contact with data

intermediate · 20 minute study

Follow the compiler through a branch

Narrowing lets one function safely handle success, pending and failure without optional-property guesswork.

Loading progressEvidence grows with practice
Useful preparation · 1 prerequisite

Use this as a map, not a lock. If these ideas are familiar, continue.

First, build a mental model

A union is a set of possible shapes. A discriminant is an observation that shrinks that set. At each branch the compiler asks which members can still exist.

  1. Use one literal field shared by every union member.
  2. Read member-specific data only after checking its discriminator.
  3. A never assignment can expose a missing case when the union grows.
  4. Changing shared mutable data can invalidate your human assumptions; prefer stable local values.
Read the codetypescript · educational example
type Save =
  | { status: 'idle' }
  | { status: 'saved'; revision: number }
  | { status: 'failed'; message: string };
function label(save: Save): string {
  switch (save.status) {
    case 'idle': return 'Ready';
    case 'saved': return `Revision ${save.revision}`;
    case 'failed': return save.message;
    default: { const impossible: never = save; return impossible; }
  }
}
  1. Before switch

    save is idle OR saved OR failed.

  2. Saved branch

    status='saved' implies revision exists; message does not.

  3. Default

    No known member remains, so save is never.

Production thinking

Take this beyond the example.

Model loading/error/success and business transitions explicitly. Avoid asserting away the error that reveals a missing state.

Sources and further reading

Your evidence

unseen is a local learning signal, not a credential or proof of production competence.

Explain the mental model, then explicitly acknowledge it. Opening a page is not evidence.

Supported retries can complete this lesson. Independent evidence and delayed review determine the skill stage.

Next lesson · Compatible shapes, excess properties and shallow readonly →