0Pricing
Frontend Academy · บทเรียน

Generics: T, extends และข้อจำกัด

เขียนฟังก์ชันและอินเทอร์เฟซแบบ generic จำกัดพารามิเตอร์ชนิดข้อมูลด้วย extends และใช้ค่าเริ่มต้นของ generic เพื่อสร้าง API ที่ยืดหยุ่น

Generics: T, extends และข้อจำกัด เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

ชนิดข้อมูลแบบทั่วไปคืออะไร

ชนิดข้อมูลแบบทั่วไปช่วยให้คุณเขียนฟังก์ชัน คลาส และอินเทอร์เฟซที่ทำงานกับชนิดข้อมูลหลายชนิดได้ โดยยังคงความปลอดภัยด้านชนิดข้อมูลไว้ แทนที่จะเขียนฟังก์ชันแยกสำหรับแต่ละชนิด คุณสามารถเขียนฟังก์ชันแบบทั่วไปหนึ่งฟังก์ชันที่กำหนดพารามิเตอร์ด้วยตัวแปรชนิดข้อมูล

ฟังก์ชันแบบทั่วไปอย่างง่าย

พารามิเตอร์ชนิดข้อมูล T ประกาศไว้ภายในวงเล็บแหลม TypeScript จะอนุมาน T จากชนิดของอาร์กิวเมนต์ จึงไม่จำเป็นต้องใส่คำอธิบายชนิดข้อมูลอย่างชัดเจนที่จุดเรียกใช้

function identity<T>(value: T): T {
  return value;
}

identity(42);      // T is inferred as number, returns number
identity('hello'); // T inferred as string
identity<boolean>(true); // explicit

อินเทอร์เฟซและชนิดข้อมูลแบบทั่วไป

กำหนดพารามิเตอร์ให้อินเทอร์เฟซและชนิดข้อมูลด้วยชนิดข้อมูลแบบทั่วไป เพื่ออธิบายโครงสร้างข้อมูลที่นำกลับมาใช้ซ้ำได้

interface Box<T> {
  value: T;
  label?: string;
}

const numBox: Box<number> = { value: 42 };
const strBox: Box<string> = { value: 'hello', label: 'greeting' };

extends — การจำกัดชนิดข้อมูลแบบทั่วไป

ใช้ T extends SomeType เพื่อจำกัดชนิดข้อมูลที่ T สามารถเป็นได้ ฟังก์ชันจะยอมรับเฉพาะชนิดข้อมูลที่เป็นไปตามข้อจำกัดเท่านั้น

function getLength<T extends { length: number }>(item: T): number {
  return item.length; // safe: T is guaranteed to have length
}

getLength('hello');       // 5
getLength([1, 2, 3]);    // 3
getLength({ length: 7 }); // 7
// getLength(42);         // Error: number has no length

keyof และข้อจำกัดของชนิดข้อมูลแบบทั่วไป

keyof T สร้างยูเนียนของคีย์คุณสมบัติของ T เมื่อนำมาใช้ร่วมกับชนิดข้อมูลแบบทั่วไป จะช่วยให้เข้าถึงคุณสมบัติได้อย่างปลอดภัยด้านชนิดข้อมูล

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Alice', age: 30 };
getProperty(user, 'name');  // string
getProperty(user, 'age');   // number
// getProperty(user, 'foo'); // Error

ค่าเริ่มต้นของชนิดข้อมูลแบบทั่วไป

กำหนดชนิดข้อมูลเริ่มต้นให้พารามิเตอร์แบบทั่วไปด้วย T = DefaultType ใช้เมื่อมีค่าเริ่มต้นที่เหมาะสม แต่ผู้เรียกใช้ยังสามารถกำหนดค่าอื่นทับได้

interface Paginated<T = unknown> {
  items: T[];
  total: number;
  page: number;
}

const rawPage: Paginated = { items: [], total: 0, page: 1 };
const typedPage: Paginated<User> = { items: [], total: 0, page: 1 };

พารามิเตอร์ชนิดข้อมูลหลายตัว

ฟังก์ชันสามารถมีพารามิเตอร์ชนิดข้อมูลอิสระหลายตัวได้

function zip<A, B>(arrA: A[], arrB: B[]): Array<[A, B]> {
  return arrA.map((a, i) => [a, arrB[i]]);
}

zip([1, 2, 3], ['a', 'b', 'c']);
// [[1,'a'], [2,'b'], [3,'c']]

คลาสแบบทั่วไป

คลาสก็สามารถเป็นชนิดข้อมูลแบบทั่วไปได้เช่นกัน ซึ่งพบได้บ่อยในโครงสร้างข้อมูลอย่างสแตก คิว และที่เก็บข้อมูลแบบสังเกตการณ์

class Stack<T> {
  private items: T[] = [];
  push(item: T) { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
  peek(): T | undefined { return this.items.at(-1); }
  get size() { return this.items.length; }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.pop(); // 2

ฟังก์ชันแบบทั่วไปชนิดไม่พร้อมกัน

ฟังก์ชันแบบทั่วไปชนิดไม่พร้อมกันพบได้บ่อยในการเรียกใช้ API ที่มีการระบุชนิดข้อมูล

async function fetchJson<T>(url: string): Promise<T> {
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json() as Promise<T>;
}

const users = await fetchJson<User[]>('/api/users');
const profile = await fetchJson<UserProfile>('/api/me');

Infer ในชนิดข้อมูลแบบมีเงื่อนไข

คีย์เวิร์ด infer ภายในชนิดข้อมูลแบบมีเงื่อนไขจะดึงชนิดข้อมูลออกจากรูปแบบที่กำหนด ใช้ในโค้ดไลบรารีเพื่อดึงชนิดข้อมูลผลลัพธ์ของฟังก์ชันหรือชนิดข้อมูลของสมาชิกในอาร์เรย์

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type ElementType<T> = T extends Array<infer E> ? E : never;

type Fn = () => { name: string };
type Result = ReturnType<Fn>; // { name: string }

ควรใช้ชนิดข้อมูลแบบทั่วไปเมื่อใด

ใช้ชนิดข้อมูลแบบทั่วไปเมื่อ: 1) ตรรกะเดียวกันใช้ได้กับชนิดข้อมูลหลายชนิด 2) คุณต้องการความสัมพันธ์ระหว่างชนิดข้อมูลอินพุตและเอาต์พุต 3) คุณกำลังสร้างโครงสร้างข้อมูลหรือยูทิลิตีที่นำกลับมาใช้ซ้ำได้ อย่าใช้ชนิดข้อมูลแบบทั่วไปเพียงเพราะทำได้ หากมีกรณีใช้งานเพียงกรณีเดียว ชนิดข้อมูลที่ระบุชัดเจนจะเข้าใจได้ง่ายกว่า

ตรวจสอบความเข้าใจ

ข้อจำกัด T extends { length: number } รับประกันอะไร?

สรุป: ชนิดข้อมูลแบบทั่วไป

ชนิดข้อมูลแบบทั่วไปช่วยกำหนดพารามิเตอร์ให้ชนิดข้อมูล ทำให้ฟังก์ชัน/คลาส/อินเทอร์เฟซหนึ่งรายการทำงานกับชนิดข้อมูลหลายชนิดได้ T extends SomeType เพิ่มข้อจำกัด keyof T ให้ยูเนียนของคีย์คุณสมบัติ ค่าเริ่มต้นแบบทั่วไปใช้ T = Default และ infer ใช้ดึงชนิดข้อมูลในชนิดข้อมูลแบบมีเงื่อนไข ใช้ชนิดข้อมูลแบบทั่วไปกับยูทิลิตีและโครงสร้างข้อมูลที่มีชนิดข้อมูลและนำกลับมาใช้ซ้ำได้

คำถามที่พบบ่อย

บทเรียน “Generics: T, extends และข้อจำกัด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Generics: T, extends และข้อจำกัด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Generics: T, extends และข้อจำกัด”

เขียนฟังก์ชันและอินเทอร์เฟซแบบ generic จำกัดพารามิเตอร์ชนิดข้อมูลด้วย extends และใช้ค่าเริ่มต้นของ generic เพื่อสร้าง API ที่ยืดหยุ่น คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “Generics: T, extends และข้อจำกัด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม

ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Generics: T, extends และข้อจำกัด
  2. ชนิดข้อมูลอรรถประโยชน์: Partial, Required, Pick และ Omit
  3. ชนิดข้อมูลแบบแมปและชนิดข้อมูลแบบมีเงื่อนไข
  4. การทำให้ชนิดข้อมูลแคบลง: typeof, instanceof และยูเนียนแบบจำแนก
← กลับไปที่ Frontend Academy