DEV Community

Cover image for Exhaustive Type Checking in React (TSX) with TypeScript’s never Type
Arka
Arka

Posted on

Exhaustive Type Checking in React (TSX) with TypeScript’s never Type

neverType 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

Enter fullscreen mode Exit fullscreen mode

👉 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;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

🔒 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)