10.7 Type Guards in Real-World Error Handling

Right, let’s talk about error handling. You’ve probably seen (or written) code that throws a generic Error for everything. It’s the equivalent of a doctor saying “something’s wrong” and then leaving the room. Useless. In the real world, you need to know what went wrong to have any hope of fixing it or reacting appropriately. This is where type guards become your best friend, turning a chaotic catch block into a well-lit, organized diagnostic room.

10.6 The asserts value Pattern for Runtime Validation

Right, let’s talk about turning your runtime checks into compile-time guarantees. You’ve probably written a function like this a hundred times: function getStringLength(str: unknown): number { if (typeof str === 'string') { // TypeScript is smart enough to know `str` is a string in here. return str.length; } throw new Error('Expected a string, you maniac.'); } It works. But it’s a bit… clunky. You have to handle the error case, and the calling code is none the wiser until it blows up at runtime. Wouldn’t it be better if we could tell the TypeScript compiler, “Hey, I’m not just checking this—I’m promising it, and if I’m wrong, I’ll crash this whole operation myself so the rest of your code can proceed with confidence”?

10.5 Assertion Functions: asserts x is T

Alright, let’s talk about asserts x is T. This is one of those TypeScript features that feels like a superpower once you get it, but first, it looks like the language designers had a bit too much coffee. It’s not magic; it’s just a very clever, formal way of telling the compiler, “Hey, trust me on this one, and by the time this function is done, I promise the type of this variable will be different.”

10.4 Writing Safe Type Guards That Don't Lie

Look, we’ve all been there. You’ve got a value that could be one of a few types, and you’re tired of the compiler giving you the side-eye every time you try to access a property. You reach for a type guard, that trusty if statement that tells TypeScript, “Relax, I’ve checked it. It’s a string.” But here’s the thing: TypeScript trusts you implicitly. It takes your word for it. This is a terrifying amount of power. With great power comes great responsibility, and the responsibility here is to not write a type guard that is a filthy, rotten liar.

10.3 User-Defined Type Guards: is Predicates

Alright, let’s get our hands dirty with user-defined type guards. You’ve already seen typeof and instanceof, and you’ve probably noticed their glaring weakness: they’re useless against data shapes you’ve invented yourself. When you’re dealing with data from an API, a config file, or a user’s input, you’re not checking for string or number; you’re checking for a string that looks like a valid email or an object that has the properties of a User.

10.2 Exhaustiveness Checking with never

Right, so you’ve built this beautiful, type-safe universe with your discriminated union. You’ve handled every known variant in your switch or if/else chain. You feel invincible. The compiler is happy. Life is good. Then your product manager slides a ticket across your desk: “Hey, can we add a new type of ActionResult for when the user’s session times out?” And just like that, your beautiful, type-safe universe has a crack in its foundation. You add the new { type: 'session_timeout' } variant to the type, you deploy, and… everything explodes at runtime in a hundred different places because you, my brilliant friend, forgot to update one of those switch statements handling ActionResult.

10.1 Discriminated Unions: A Common Discriminant Field Pattern

Right, let’s talk about one of the most satisfying patterns you’ll use in TypeScript: the discriminated union. You’ve probably felt the pain of having a function that accepts a few different, but related, types. You check for one property to see if it’s type A, then another for type B, and your code becomes a fragile mess of if statements and type assertions. It feels clunky because it is clunky. Discriminated unions are how TypeScript and you formally agree on a system to tell these types apart.

— joke —

...