Throwing Error vs Fallback Using never Type
📝 Context
Should you fail fast (throw error) or fail gracefully (fallback)? The answer: both, depending on environment.
🚨 Without TypeScript – The Problem
function Theme({ mode }) { switch (mode) { case "light": return <p>Light Mode</p>; case "dark": return <p>Dark Mode</p>; default: return <p>Unknown Mode</p>; // ❌ hides bug silently } }
✅ With TypeScript + never – Fail Fast in Dev, Fallback in Prod
type ThemeMode = "light" | "dark"; function Theme({ mode }: { mode: ThemeMode }) { switch (mode) { case "light": return <p>Light Mode</p>; case "dark": return <p>Dark Mode</p>; default: { const _exhaustive: never = mode; if (process.env.NODE_ENV === "development") { throw new Error("Unhandled theme mode: " + mode); } // In production → fallback console.warn("Unexpected theme mode:", mode); return <p>Defaulting to Light Mode</p>; } } }
🎯 Takeaway
- Dev mode: Throw error → surfaces missing cases quickly.
- Prod mode: Fallback UI + logs → users don’t experience crashes.
- Balance = strict during development, resilient in production.
Top comments (1)
Nice pattern!
One neat trick I recently learned: you can also use
satisfies
to avoid creating the_exhaustive
variable:TypeScript Playground