App.tsxCourse
TypeScript and React
A typed name, then an object, a class, a copy before a change, a union of cases, and an interface that lists the methods.
- namestringlatte
- centsnumber450
- readybooleantrue
6 lessons, in orderFree to read
Syllabus
Basics
The types, explained, then an object you can name and call.
-
01
TypeScript from zero: a name has a type
2 min read
A TypeScript name can carry a type. name is a string, cents is a number, and ready is a boolean. The program prints latte $4.50 ready.
const name: string = "latte"; const cents: number = 450; const ready: boolean = true; const status: string = ready ? "ready" : "sold out"; const frac = String(cents % 100).padStart(2, "0"); console.log(name + " $" + Math.floor(cents / 100) + "." + frac + " " + status);latte $4.50 ready -
02
TypeScript from zero: an object has fields
2 min read
An object type names the fields. Item has a drink and a price in cents. label takes an Item and the program prints latte $4.50.
Builds on lesson 1.
type Item = { name: string; cents: number; }; function label(item: Item): string { const frac = String(item.cents % 100).padStart(2, "0"); return item.name + " $" + Math.floor(item.cents / 100) + "." + frac; } const latte: Item = { name: "latte", cents: 450 }; console.log(label(latte));latte $4.50
Practice
A rule that prevents a bug, then a program that uses the object.
-
03
A class holds the fields and the method together. new Item makes a latte. label prints latte $4.50.
Builds on lessons 1 through 2.
class Item { name: string; cents: number; constructor(name: string, cents: number) { this.name = name; this.cents = cents; } label(): string { const frac = String(this.cents % 100).padStart(2, "0"); return this.name + " $" + Math.floor(this.cents / 100) + "." + frac; } } const latte = new Item("latte", 450); console.log(latte.label());latte $4.50 -
04
An object spread copies the fields and replaces one. The original latte stays 450 cents. The tipped copy is 540. The program prints 450 540.
Builds on lessons 1 through 3.
const item = { name: "latte", cents: 450 }; const tipped = { ...item, cents: 540 }; console.log(item.cents, tipped.cents);450 540
Further
One more idea, then a program that puts the pieces together.
-
05
A union is a value that is one of several shapes. Paid is yes with the cents, or no. Reading yes prints paid 450. Reading no prints unpaid.
Builds on lessons 1 through 4.
type Paid = { kind: "yes"; cents: number } | { kind: "no" }; function read(a: Paid): string { if (a.kind === "yes") return "paid " + a.cents; return "unpaid"; } console.log(read({ kind: "yes", cents: 450 })); console.log(read({ kind: "no" }));paid 450 unpaid -
06
An interface lists the methods a function needs. Labeller asks for label. Item has label. show prints latte $4.50.
Builds on lessons 1 through 5.
interface Labeller { label(): string; } class Item implements Labeller { name: string; cents: number; constructor(name: string, cents: number) { this.name = name; this.cents = cents; } label(): string { const frac = String(this.cents % 100).padStart(2, "0"); return this.name + " $" + Math.floor(this.cents / 100) + "." + frac; } } function show(item: Labeller): void { console.log(item.label()); } show(new Item("latte", 450));latte $4.50
Readings
Shorter pieces in the same language. Any order is fine once the lessons feel familiar.
-
Make illegal states unrepresentable
2 min
GoByte Skills #15: Three booleans are 8 states and your screen means three. Model React state as a tagged union and the compiler rules out the other 5. Validate the data at the edge, and the inside stays honest.
-
State is a snapshot
2 min
GoByte Skills #14: In React, count is not a live variable. Each render gets its own constant, and a click handler only ever sees the render it was born in. That is why setCount(count + 1) three times adds one, and how the updater fixes it.
-
TypeScript narrowing: typeof is the bouncer
2 min
GoByte Skills #13: typeof does not just check a type, it proves one. After the check each branch gets a narrower type and the compiler holds you to it. A handwritten type guard only promises.