Prologue

How to Read This Book

Ask a senior developer any question about TypeScript, and you’ll get the same answer: “It depends.”

Should you use interface or type? It depends. Should you avoid any at all costs? It depends. Should you keep strict mode on? Yes. We have a few opinions.

This book doesn’t pretend there’s one right way to write TypeScript. Instead, it does what your team does every day: it argues about it.

Here’s what that looks like:

Oded: “Fine. For critical paths — auth, payments — I’ll wrap. For the admin dashboard’s logging middleware? I’m using req.body directly and you can’t stop me.”

Noam: “I can block your PR.”

Oded: “You already block all my PRs.”

That’s an exchange from Chapter 1. The code that sparked it, the argument that followed, and the verdict the room eventually reached — that’s every chapter of this book.


The Format

Every chapter follows a debate structure:

The Principle — An expert states a TypeScript principle. Something that sounds reasonable, maybe even obvious. Something you might nod along to in a conference talk.

The Debate — Then the practitioners take it to their own code. They challenge it with real-world experience, edge cases, production war stories, and strong opinions. They argue with each other. They show code. They get heated.

The Turn — Sometimes another caller, a changed input, or a question sends the discussion in a different direction. A rule that seemed settled may need an exception.

The Verdict — Some chapters land on a clear answer. A practical ruling with code you can adopt tomorrow. Others end honestly: it depends — and we tell you on what.

The Debate Continues marks a disagreement that remains open after the evidence, with the choice depending on what the callers need.

Additional Takes explore related cases after the main argument; a chapter with only one has an Additional Take.

Not every debate has a winner. That’s not a cop-out. Some questions in software engineering are genuinely contextual, and pretending otherwise would be dishonest. When we say “it depends,” we’ll tell you exactly what it depends on.


The Cast

This book features two tiers of characters:

The Experts bring theory, compiler knowledge, and experience. They usually set the opening principle and intervene when those specialties help. Their advice can be challenged too; knowing what the compiler does does not settle what a team should choose.

The Professionals are the practitioners who drive every debate. They represent the voices you hear in real engineering teams — the type safety absolutist, the “just ship it” advocate, the data person who won’t accept a claim without benchmarks, the FP purist, the OOP defender, and the one person who just asks hard questions until everyone wants to throw something at them.

You’ll get to know them in the next chapter. By the third debate, you’ll start predicting who’s going to object and why. That’s by design.


Where We Stand

Every book has a perspective. Here’s ours:

We lean toward functional programming patterns — immutability, pure functions, declarative code. We think these patterns make TypeScript code safer, more predictable, and often simpler. But we’re not zealots. Object-oriented patterns have their place, and we give them a fair hearing.

We believe in strong typing. Not because types are fun to write, but because they catch bugs before your users do. We’re skeptical of any, suspicious of unvalidated type assertions, and enthusiastic about TypeScript’s strict mode.

We care about production. Theory is valuable, but only insofar as it survives contact with real code, real deadlines, and real legacy systems. If a pattern only works in a greenfield project with unlimited time, we’ll say so.


The Code

The examples target TypeScript 7, checked with 7.0.2. Strict mode is on by default in TypeScript 7, and we keep it on. The checks also enable exactOptionalPropertyTypes, except when comparing its behavior with the flag off.

We leave noUncheckedIndexedAccess off. The configuration generated by tsc --init turns it on, which makes array and index-signature reads include undefined. If you try an example in a fresh project, that setting can explain an extra error. The repository documents the full configuration.

When a character claims that an approach is better, they show you the code. When another character disagrees, they show you why it breaks. Some examples deliberately produce errors; others reuse definitions from earlier in the conversation or show alternative implementations. The checks account for that context.

You don’t need to run the examples to follow along. If you want to, the repository’s README explains how to run the checks with the pinned compiler.


How to Read

You can read this book front to back — the chapters build in complexity from basic type system concepts through advanced patterns to production concerns.

Or you can jump to whatever debate your team is currently having. Each chapter opens a new argument. Some build on earlier examples and type-system concepts. If you’re in the middle of a migration and someone just asked whether to use interface or type, go straight to that chapter. The argument is already in progress.

Either way, pay attention to the characters. Their disagreements aren’t artificial — they represent genuine tensions in how we write TypeScript. The moments where you find yourself siding with one character over another? That’s you figuring out what kind of TypeScript developer you are.

Welcome to the debate.