Theory

Why strict is the whole point

So far we've used strict: true without digging in. This lesson is about why strictness is the whole point of TypeScript. Without it, TypeScript catches almost nothing — it's just "JavaScript with type syntax." With it, the types start demanding real precision.

Three flags we'll cover:

noUncheckedIndexedAccess. An array index might not exist:

const arr = [1, 2, 3];
const x = arr[10];    // undefined at runtime, but the type says `number`?!

With this flag, arr[10] becomes number | undefined. You can't pretend an index is always there. Recall lesson 17's date.toISOString().split('T')[0] — the compiler forces you to handle the case where [0] isn't there.

exactOptionalPropertyTypes. "Field absent" and "field present but undefined" differ:

interface T { x?: string }
const a: T = {};                 // ✅ x is absent
const b: T = { x: undefined };   // ❌ with exactOptional — "present but undefined" ≠ "absent"

Subtle but important: hdurl?: string means "may be absent", not "may hold an undefined value".

assertNever() — an exhaustiveness guarantee. This is the cleverest. assertNever(value: never) goes in a switch's default branch. If you add a new variant to a union and forget to handle it, value is no longer never, and assertNever becomes a compile error — pointing at exactly the switch you forgot to update.

That turns "I added a variant and forgot to handle it somewhere" from a silent runtime bug into a compiler error that points a finger at the code. That's exactly what a growing app needs: change a type in one place, and the compiler finds every spot that needs updating.