Book: The TypeScript Type System — From Generics to DSL-Level Types
Also by me: The TypeScript Library — the 5-book collection
My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
Me: xgabriel.com | GitHub
A function takes a userId: string and an orderId: string .
During a refactor, two arguments cross. The new call reads
refund(orderId, userId) instead of refund(userId, orderId) .
The checker shrugs. Both are strings. Both pass. The unit test for
refund ran against a happy-path fixture where the IDs happened
to be different lengths, so the SQL still returned a row. Just
the wrong one. A customer reads someone else's order history
before the on-call notices.
This bug is older than TypeScript. Languages with nominal type
systems can declare a UserId distinct from every other string,
and the compiler refuses to confuse them. TypeScript is
structural. A string is a string .…