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.
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 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.
⌨️ 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): returnstrueexactly when the value’s type is"number"— one operator from 1.1 tells you a value’s type. - Write
withTaxChecked(price): iftypeOk(price)fails, RETURN the string"type error: not a number"; otherwise returnprice * 1.25. - Print
withTaxChecked(100), thenwithTaxChecked("100")— one honest answer, one caught mistake.
when you press RUN, the console must show exactly:
✏️ 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.
🗣️ 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.