ข้ามไปยังเนื้อหา

Generics

สมมติคุณอยากได้ function ที่คืนค่าอะไรก็ตามที่คุณส่งเข้าไป ถ้าไม่มี generics คุณจะเจอทางเลือกที่แย่ทั้งคู่:

// Option A: one type only — not reusable
function identityStr(x: string): string { return x; }
// Option B: any — reusable, but throws away all type information
function identityAny(x: any): any { return x; }
const a = identityAny(42);
a.toUpperCase(); // 💥 no error at compile time — any hides the bug

any ทำให้ function reuse ได้ก็จริง แต่ทำให้ compiler ตาบอด — ความเชื่อมโยงระหว่าง type ของ input กับ output หายไปหมด Generics เก็บความเชื่อมโยงนั้นไว้

function identity<T>(x: T): T { return x; }
const n = identity(42); // T inferred as number → n: number
const s = identity("hi"); // T inferred as string → s: string
n.toUpperCase(); // ❌ Error: number has no toUpperCase — the bug is caught

T คือ type parameter — ตัวยึดที่ผู้เรียก (หรือ inference) เป็นคนเติมค่าให้ function ตัวนี้ทำงานได้กับทุก type และ return type ก็ยังตาม type ของ argument ได้เป๊ะ

generic คือ function ในระดับ type — รับ type เป็น input แล้วผลิต type เป็น output identity<T> บอกว่า “สำหรับ type T ใด ๆ ก็ตาม รับ T แล้วคืน T” อันนี้เรียกว่า parametric polymorphism — implementation เดียว ที่ parameterize ด้วย type

flowchart LR
  impl["generic เดียว
identity ของ T"] --> callN["เรียกด้วย number
คืน number"]
  impl --> callS["เรียกด้วย string
คืน string"]
  impl --> callU["เรียกด้วย User
คืน User"]
A generic is one implementation over many types
บทเรียนสิ่งที่คุณจะได้เรียน
Functions & constraintstype parameter, constraint ด้วย extends, default type parameter
Classes & interfacesgeneric class, interface และ type parameter ต่อ method
Conditional typesT extends U ? X : Y และการ distribute ผ่าน union
Inference & infertype argument ถูก infer อย่างไร และการดึง type ออกด้วย infer
generics เก็บอะไรไว้ที่ `any` ทิ้งไป?
ใน `function identity<T>(x: T): T` `T` คืออะไร?
ชื่อของ "implementation เดียวที่ parameterize ด้วย type" คืออะไร?