Overview
Generics คือฟีเจอร์ที่ทำให้ TypeScript เหนือกว่า JavaScript อย่างมาก มันช่วยให้เราเขียนโค้ดที่ "ทำงานกับ Type อะไรก็ได้" (Reusable) โดยที่เราไม่ต้อง Fix Type ตายตัว และไม่ต้องถอยไปใช้ any ที่ไม่ปลอดภัย
Key Ideas
1. Concept <T>
คิดซะว่า Generics คือ "ตัวแปรสำหรับ Type"
เวลาเราเรียกใช้ฟังก์ชัน เราส่งค่า (Argument) เข้าไป
เวลาเราใช้ Generics เราส่ง Type เข้าไป
โดยนิยมใช้ตัวอักษร T (Type), K (Key), V (Value)
2. Constraints (extends)
เราสามารถจำกัดขอบเขตของ Type ที่ส่งมาได้ เช่น "ต้องเป็น Type ที่มี property .length เท่านั้นนะ"
Example
// 1. Generic Function
// รับอะไรมา ก็คืนค่านั้นกลับไป (โดย TS ยังรู้ Type นั้นอยู่)
function identity<T>(arg: T): T {
return arg;
}
const n = identity(10); // T = number
const s = identity("Hi"); // T = string
// 2. Generic Interface
interface ApiResponse<T> {
status: number;
data: T; // data จะเป็นอะไรก็ได้ ตามที่ส่งมา
}
interface User {
name: string;
}
interface Product {
title: string;
price: number;
}
const response1: ApiResponse<User> = {
status: 200,
data: { name: "Alice" },
};
const response2: ApiResponse<Product> = {
status: 200,
data: { title: "Pen", price: 20 },
};
Pitfalls (สิ่งที่ควรระวัง)
❌ 1. ใช้ Generics โดยไม่จำเป็น
ถ้าฟังก์ชันไม่ได้มีความสัมพันธ์ระหว่าง Input/Output หรือ Type ไม่ได้ถูกใช้ซ้ำ ก็ไม่ต้องใช้
// ❌ ซับซ้อนเกินความจำเป็น
function log<T>(arg: T) {
console.log(arg);
}
// ✅ ใช้ any หรือ unknown ก็พอ ถ้าแค่จะปริ้นท์
function log(arg: unknown) {
console.log(arg);
}
❌ 2. ลืม Default Generic Type
ถ้าใช้ Generics บ่อยๆ การกำหนดค่า Default จะช่วยให้เรียกใช้ง่ายขึ้น
type Response<T = any> = ...