Skip to main content

Why Types Exist

intermediate13 min readLesson 85 of 143

The failure modes types prevent, inference vs annotation, structural typing, and strict mode as a philosophy.

JavaScript fails at runtime: user.nmae is undefined three screens away from the typo. TypeScript moves whole classes of those failures to the editor, before the code ever runs.

What types buy you

function subtotal(items: CartItem[]): number {
  return items.reduce((sum, i) => sum + i.price * i.qty, 0);
}
subtotal("cart"); // โœ— compile error
subtotal([{ price: 5, qty: 2 }]); // โœ“ โ€” and price/qty autocomplete

Renaming a field updates every usage; a missed callsite turns red. That is not ceremony โ€” it is a searchable, checkable contract.

Inference first, annotations at boundaries

TypeScript infers most types โ€” annotate where inference cannot help:

const rates = [0.2, 0.15];            // inferred: number[]
function tax(amount: number) { ... }  // boundary: parameters
const total = tax(100);               // inferred: number

Annotating every local is noise; annotating nothing pushes surprises to call sites. The convention: annotate function parameters and exported APIs, let locals infer.

Structural typing

TypeScript types by shape, not name โ€” any object with the right members fits, no inheritance required:

type Point = { x: number; y: number };
const p = { x: 1, y: 2, label: "origin" }; // OK: has x and y (extra is fine here)

Run tsc --noEmit as your gate: it checks without emitting. Strict mode (strict: true) enables the checks that matter โ€” null checking above all.

Now practice

Shapes & Inference โ€” PracticeThink in shapes: build objects that satisfy contracts, normalize messy data, and apply utility-type logic at runtime.3 challenges ยท ยท ~15 min