ข้ามไปเนื้อหาหลัก

TypeScript Exhaustive Check — ให้ compiler บอกเมื่อลืม case

ใช้ never เพื่อให้ TypeScript error ตอน build ถ้า switch/if ไม่ครอบคลุมทุก union member — ป้องกัน bug เมื่อเพิ่ม type ใหม่แล้วลืมอัพเดตโค้ด

type Status = 'active' | 'inactive' | 'pending';

function getLabel(status: Status): string {
  switch (status) {
    case 'active':   return 'กำลังใช้งาน';
    case 'inactive': return 'ปิดใช้งาน';
    case 'pending':  return 'รอดำเนินการ';
    default:
      // ถ้า status ครบแล้ว default จะ unreachable
      // ถ้าเพิ่ม 'archived' ใน Status แต่ลืมเพิ่ม case → compile error
      const _exhaustive: never = status;
      throw new Error(`Unhandled status: ${_exhaustive}`);
  }
}

Helper function:

function assertNever(value: never, message?: string): never {
  throw new Error(message ?? `Unhandled case: ${JSON.stringify(value)}`);
}

// ใช้แบบ clean กว่า
default: return assertNever(status);

pattern นี้มีประโยชน์มากใน discriminated union ที่เพิ่ม member บ่อย เช่น action types ใน state machine หรือ API response variants — TypeScript จะ fail ตรง assertNever ทันทีที่ลืม handle