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 lengthkeyof และข้อจำกัดของชนิดข้อมูลแบบทั่วไป
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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Generics: T, extends และข้อจำกัด
- ชนิดข้อมูลอรรถประโยชน์: Partial, Required, Pick และ Omit
- ชนิดข้อมูลแบบแมปและชนิดข้อมูลแบบมีเงื่อนไข
- การทำให้ชนิดข้อมูลแคบลง: typeof, instanceof และยูเนียนแบบจำแนก