DEV Community

Cover image for Handling Unexpected API Values in React (TSX) Using TypeScript Union Types and never
Arka
Arka

Posted on

Handling Unexpected API Values in React (TSX) Using TypeScript Union Types and never

Behavior When API Returns a Value Not in the Union Type


📝 Context

You define a strict union type like "admin" | "editor" | "viewer". But what if your API returns "super-admin"? Without TS, your UI may behave unpredictably.


🚨 Without TypeScript – The Problem

// React without TypeScript
function UserRoleMessage({ role }) {
  switch (role) {
    case "admin":
      return <p>Welcome Admin</p>;
    case "editor":
      return <p>Welcome Editor</p>;
    case "viewer":
      return <p>Welcome Viewer</p>;
    default:
      return <p>Unknown Role</p>;
  }
}

// API mistakenly sends "super-admin"
<UserRoleMessage role="super-admin" />;
// ❌ User just sees "Unknown Role"

Enter fullscreen mode Exit fullscreen mode

👉 Issue

No warning at compile time. The bug slips through until runtime.


✅ With TypeScript + never – Safer API Handling

type UserRole = "admin" | "editor" | "viewer";

function UserRoleMessage({ role }: { role: UserRole }) {
  switch (role) {
    case "admin":
      return <p>Welcome Admin</p>;
    case "editor":
      return <p>Welcome Editor</p>;
    case "viewer":
      return <p>Welcome Viewer</p>;
    default: {
      // Exhaustive check
      const _exhaustive: never = role;
      return _exhaustive;
    }
  }
}

// âś… Best practice: validate API before assignment
function validateRole(role: string): UserRole | null {
  if (role === "admin" || role === "editor" || role === "viewer") {
    return role;
  }
  return null;
}

const apiRole = "super-admin"; // From backend
const safeRole = validateRole(apiRole);
<UserRoleMessage role={safeRole ?? "viewer"} />;

Enter fullscreen mode Exit fullscreen mode

🎯 Takeaway

  • Without TS: Bad API values silently break UI.
  • With TS: Union + never ensures exhaustiveness. Validation guards catch invalid values at runtime.

Top comments (0)