linkedinlogo
Javascript
Javascript

How do TypeScript discriminated unions with never type guards enforce complete error handling exhaustiveness at compile time?

November 28, 2025

Discriminated unions with assertNever() catch unhandled cases in switch statements, forcing developers to handle all variants. TypeScript errors if new union members aren't covered. Prevents runtime "forgotten case" bugs in API responses, GraphQL resolvers, and state machines. Trending for Zod schemas and tRPC endpoints.

Code Example:-

Code

type ApiResponse = 
  | { status: 'success'; data: User }
  | { status: 'loading' }
  | { status: 'error'; code: 'NOT_FOUND' | 'VALIDATION' };

function handleApiResponse(response: ApiResponse): void {
  switch (response.status) {
    case 'success':
      displayUser(response.data);
      break;
    case 'loading':
      showSpinner();
      break;
    case 'error':
      if (response.code === 'NOT_FOUND') {
        show404();
      } else if (response.code === 'VALIDATION') {
        showValidationErrors();
      }
      break;
    default:
      // TypeScript errors here if new status added
      const exhaustiveCheck: never = response;
      throw new Error(`Unhandled status: ${exhaustiveCheck.status}`);
  }
}
      
bg-image
Company Deck
PDF, 3MB

© 2026 Zignuts Technolab. All Rights Reserved.