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

Discriminated Unions — type narrowing ที่ TypeScript ชอบที่สุด

Discriminated union คือ union type ที่มี “discriminant” — field ที่ค่าแยกจากกันชัดเจน TypeScript ใช้ field นั้น narrow type ให้อัตโนมัติใน switch/if

type Result<T> =
  | { status: 'ok';    data: T }
  | { status: 'error'; message: string }
  | { status: 'loading' };

function handle<T>(result: Result<T>) {
  switch (result.status) {
    case 'ok':
      return result.data;        // TS รู้ว่า data มีอยู่
    case 'error':
      return result.message;     // TS รู้ว่า message มีอยู่
    case 'loading':
      return null;
  }
}

Exhaustiveness check — ให้ compiler แจ้งถ้าลืม case:

function assertNever(x: never): never {
  throw new Error(`Unexpected value: ${x}`);
}

// ถ้าเพิ่ม status: 'cancelled' ในอนาคต → TS error ที่ assertNever ทันที
default: return assertNever(result);

Pattern ที่ใช้บ่อย: API response, UI state machine, command/event system

Discriminant ไม่ต้องเป็น string เท่านั้น — boolean หรือ literal number ก็ได้