Skip to content

Enum

ถ้าเราใช้งาน enum เราไม่สามารถ assign string ตรงๆ ไปได้ เช่น เราไม่สามารถใส่ DRAFT ลงไปใน PostState ได้

typescript
enum PostState {
    Draft = "DRAFT",
    Scheduled = "SCHEDULED",
    Published = "PUBLISHED",
}

const state1: PostState = PostState.Draft;
const state2: PostState = "IDEA";    // ❌ Error: Type '"IDEA"' is not assignable to type 'PostState'
const state3: PostState = "DRAFT";   // ❌ Error: Type '"DRAFT"' is not assignable to type 'PostState'.

บางทีเราสามารถใช้ as เพื่อ casting type ได้ แต่มันก็ไม่เกิดประโยชน์เท่าไหร่ เพราะความสามารถในการเช็ค Type หายไป

typescript
const state2: PostState = "IDEA" as PostState.Draft;   // ตรงนี้มันควรจะ Error ใช่มั้ย
const state3: PostState = "DRAFT" as PostState.Draft;

ปัญหาอีกอย่าง ถ้าเราใช้ enum อยู่ใน Library แล้วเราไม่สามารถส่ง string "DRAFT" ที่มีใน enum PostState ได้เลย เราอาจจะต้อง import enum เข้ามาใช้งาน และถ้าเป็นภาษา JS ละ ??

เราสามารถใช้ const object แทน enum ใน TypeScript ได้

typescript
const PostState = {
    Draft : "DRAFT",
    Scheduled : "SCHEDULED",
    Published : "PUBLISHED",
} as const;

เมื่อเราใช้ as const แต่ละ property ของ object จะเป็น readonly ทันที

Enum Object Const

เราสามารถทำ Type Alias เพื่อมา check type ของ PostState ได้

typescript
type PostStateType = PostState; // ❌ Error เราไม่สามารถเอา js variable มาเป็น type ได้
type PostStateType = typeof PostState; //เราสามารถใช้ `typeof` เพื่อเอา type ของ js variable มาได้แทน

แบบนี้เราจะได้ Key ของ object PostState

typescript
type PostStateType = keyof typeof PostState;
// type PostStateType = "Draft" | "Scheduled" | "Published"

แบบนี้เราจะได้ Value ของ object PostState พอเป็นแบบนี้เราก็เอามา check type ได้แล้ว

typescript
type PostStateType = typeof PostState[keyof typeof PostState];
// type PostStateType = "DRAFT" | "SCHEDULED" | "PUBLISHED"

เรามาดูตัวอย่างแบบเต็มๆ กันดีกว่า

typescript
const PostState = {
    Draft : "DRAFT",
    Scheduled : "SCHEDULED",
    Published : "PUBLISHED",
} as const;

type PostStateType = typeof PostState[keyof typeof PostState];
// type PostStateType = "DRAFT" | "SCHEDULED" | "PUBLISHED"

const state1: PostStateType = PostState.Draft;  // อันนี้ เราสามารใช้งานได้เหมือน enum เลย
const state2: PostStateType = "IDEA";           // อันนี้ ❌ Error: Type '"IDEA"' is not assignable to type 'PostStateType'
const state3: PostStateType = "DRAFT";          // เย้ๆ เราสามารถ passing string ที่ match กับ value ใน PostState ได้แล้ว

ขอบคุณตัวอย่างจากคุณ Andrew Burgess How to use TypeScript Enums and why not to, maybe

ทำ Type Utility ใช้งานเอง

typescript
// Type Utility
type Enum<T> = T[keyof T];

type PostStateType = Enum<typeof PostState>;

อ่านเพิ่มน้าาา