TypeScript discriminated unions: the pattern I reach for daily
How a small modeling discipline turns runtime branches into compile-time guarantees — and makes refactors fearless.
Most TypeScript bugs I see in code review boil down to the same thing: a state was modeled as a bag of optional fields when it should have been a discriminated union.
The shape
type Result<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: string };Now you can't accidentally read .data while loading. The compiler stops you. That's the whole game.
Tagged
Keep reading
All posts →Shipping SSR on Next.js: how I cut page loads by 35%
A pragmatic walk-through of the rendering, caching and image strategies behind a real CMS revamp — including the trade-offs nobody talks about.
Docker + Azure DevOps: a CI/CD recipe that halves release time
The exact pipeline structure, caching tricks and image layering rules that took our deploys from 18 minutes to under 9.
Design systems with Tailwind: lessons from real-world products
Tokens, primitives, and the discipline it takes to keep a Tailwind codebase from devolving into utility-class soup.