JS Sketchbooksee JavaScript think ✏️
← back to phase 8

8.5 — A taste of TypeScript

Every type disaster you’ve met — "5" - 5 coercion (1.9), reading properties off undefined (8.4) — shares one trait: JavaScript only notices while running, sometimes in front of a user. TypeScript’s bet: declare each value’s type as a label, and let a checker verify the whole file BEFORE it ever runs.

This is a taste, not a course — but a necessary taste: Playwright projects are TypeScript by default, so the job you’re training for reads it every day.

watch it happen
function withTax(price: number): number {
  return price * 1.25;
}

withTax(100);     // ✓
withTax("100");   // ✗ caught BEFORE running

interface User {
  name: string;
  age: number;
}

const u: User = { name: "Ada", age: 36 };

Start with the pain: JavaScript discovers type mistakes at RUN TIME. "5" - 5 silently coerces (1.9); user.cat.name explodes mid-run (8.4). If the wrong value only arrives on the 97th test run, that’s when you find out. What if mistakes surfaced while WRITING?

the function machine — now with a checked gatewithTaxprice * 1.25gate:numberchute:numberJavaScript discovers type mistakes only AT RUN TIME — 1.9 was an entirelesson of those surprises
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

The checker is a program called tsc (the TypeScript compiler), and it’s usually wired into an npm script (8.2!) plus your editor. Files end in .ts — the same code, one letter of extension, a whole safety net.

You annotate less than you’d think: TypeScript infers. Write const x = 5 and x is already known to be a number — no label needed. Professionals annotate the boundaries (function parameters, returns, API shapes) and let inference handle the middle.

There’s an escape hatch: the type any turns checking off for a value. It exists for migrations and emergencies — every any is a hole in the net, and teams treat them like TODOs.

One honest boundary: the checker verifies your source code’s promises — it cannot check data arriving at runtime from the outside world (an API response is whatever the server sent). That’s why tests still matter in typed projects: types catch the mistakes you write, tests catch the behavior you ship. You need both — and you’re training for the second.

your turn

⌨️ build the type checker

The sandbox speaks plain JavaScript, so build the essence of TypeScript yourself: a gate that inspects a value’s type BEFORE the real work is allowed to happen.

requirements:

  • Write typeOk(value): returns true exactly when the value’s type is "number" — one operator from 1.1 tells you a value’s type.
  • Write withTaxChecked(price): if typeOk(price) fails, RETURN the string "type error: not a number"; otherwise return price * 1.25.
  • Print withTaxChecked(100), then withTaxChecked("100") — one honest answer, one caught mistake.

when you press RUN, the console must show exactly:

125
type error: not a number

✏️ Quick check 1

TypeScript rejects withTax("100"). Does it catch this before the program runs, or while it runs?

✏️ Quick check 2

After compiling to JavaScript, do the type annotations still exist in the running code? Type yes or no.

✏️ Quick check 3

interface User requires name: string and age: number. Does { name: "Mo" } satisfy it? Type yes or no.

teach it back

🗣️ Now teach it back

Explain TypeScript to a friend in three beats: what a type annotation is, when the checking happens (and what happens to the types afterward), and why Playwright projects choose TS.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
TypeScript = JS + type labels: price: number declares the pen (1.1) on the label; interfaces name whole object shapes. Annotate boundaries; inference fills the middle.
Checking happens BEFORE running (tsc + your editor) — wrong-type calls bounce at your desk. Compiling then ERASES all types: what runs is plain JavaScript.
Playwright projects are TS by default (playwright.config.ts): autocomplete on every page action, instant typo-catching. Types catch written mistakes; tests catch shipped behavior — you need both.