never
Type for Exhaustive Type Checking in TypeScript
Context
- When handling union types in React apps (e.g.,
"loading" | "success" | "error"
), developers often forget to cover every case. - Without TypeScript, this can silently break your UI at runtime. With TypeScript’s never, you get compile-time safety that forces you to be exhaustive.
🚨 Without TypeScript – The Problem
// React without TypeScript import React from "react"; function StatusMessage({ status }) { switch (status) { case "loading": return <p>Loading...</p>; case "success": return <p>Data loaded successfully!</p>; // ❌ Forgot to handle "error" default: // Will silently run for unexpected values return <p>Unknown state</p>; } } // At runtime, this could happen: <StatusMessage status="error" />; // UI shows "Unknown state" instead of an error message
👉 Issue
You don’t get any warning if "error" is unhandled. The bug only appears when the app runs.
✅ With TypeScript + never – Compile-Time Safety
// React with TypeScript import React from "react"; type Status = "loading" | "success" | "error"; function StatusMessage({ status }: { status: Status }) { switch (status) { case "loading": return <p>Loading...</p>; case "success": return <p>Data loaded successfully!</p>; case "error": return <p>Something went wrong.</p>; default: { // Exhaustive check using never const _exhaustive: never = status; return _exhaustive; } } }
🔒 Why this is safe:
- If you add a new state (e.g., "idle") to Status but forget to handle it in the switch, TypeScript will throw a compile-time error at the never line.
- This guarantees you can’t accidentally miss a case.
🎯 Takeaway
- Without TS: Missed cases only show up at runtime → unstable apps.
- With TS + never: TypeScript enforces exhaustive handling at compile-time → safer apps and fewer bugs.
Top comments (0)