Dark mode
Utility Types ที่ควรรู้ใน TypeScript
Utility Types คือประเภทที่ TypeScript เตรียมไว้ให้สำหรับแปลงหรือจัดการกับชนิดข้อมูล (type) ให้สะดวกและปลอดภัยมากขึ้น เหมาะกับงานจริงในโปรเจกต์ยุคใหม่
Partial<T>
(ทำให้เป็นบางส่วน)
แปลงทุก property ของ type ที่ระบุให้เป็น optional เหมาะกับกรณีที่ต้องการอัปเดตหรือแก้ไขบางส่วนของ object
ts
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
// Partial<Todo> ทำให้ทุก property เป็น optional
// สามารถส่งเฉพาะ property ที่ต้องการอัปเดตได้
return { ...todo, ...fieldsToUpdate };
}
Required<T>
(ทำให้จำเป็นต้องมี)
แปลงทุก property ของ type ที่ระบุให้เป็น required (บังคับต้องมีทุก property) ตรงข้ามกับ Partial
ts
interface Props {
a?: number;
b?: string;
}
const obj: Required<Props> = { a: 1, b: "hi" }; // ต้องมีทั้ง a และ b
// Required<Props> บังคับให้ต้องมีทุก property แม้จะประกาศเป็น optional ก็ตาม
Readonly<T>
(ทำให้อ่านได้อย่างเดียว)
แปลงทุก property ของ type ที่ระบุให้เป็น readonly (ห้ามแก้ไขค่า)
ts
interface Todo {
title: string;
}
const todo: Readonly<Todo> = { title: "Hello" };
// todo.title = "World"; // Error: read-only
// Readonly<Todo> ทำให้ไม่สามารถแก้ไขค่าหลังจากกำหนดค่าครั้งแรก
Record<K,T>
(สร้างบันทึก)
สร้าง object type ที่ key เป็นชุดค่าที่กำหนด และ value เป็น type ที่กำหนด
ts
type CatName = "miffy" | "boris";
interface CatInfo { age: number; }
const cats: Record<CatName, CatInfo> = {
miffy: { age: 10 },
boris: { age: 5 }
};
// Record<K, T> สร้าง object ที่มี key เป็นประเภท K และ value เป็นประเภท T
// ในที่นี้ key ต้องเป็น "miffy" หรือ "boris" เท่านั้น และ value ต้องเป็น CatInfo
Pick<T,K>
(เลือกเฉพาะ)
เลือกเฉพาะ property ที่ต้องการจาก type
ts
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
// Pick<Todo, "title" | "completed"> เลือกเฉพาะ property title และ completed จาก Todo
// ผลลัพธ์คือ type ที่มีแค่ { title: string; completed: boolean; }
Omit<T,K>
(ละเว้น)
เหมือน Pick แต่เป็นการ "ตัดออก" ไม่เอา property ที่ระบุ
ts
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
// Omit<Todo, "description"> ตัด property description ออกจาก Todo
// ผลลัพธ์คือ type ที่มี { title: string; completed: boolean; }
Exclude<T,U>
(ไม่รวม)
ตัดค่าที่ตรงกับ type ที่ระบุออกจาก union type
ts
type T = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
// Exclude<T, U> ตัดค่าที่เป็น U ออกจาก T
// ในที่นี้ตัด "a" ออกจาก "a" | "b" | "c" เหลือ "b" | "c"
Extract<T,U>
(แยกออกมา)
เลือกเฉพาะค่าที่ตรงกับ type ที่ระบุจาก union type
ts
type T = Extract<"a" | "b" | "c", "a" | "f">; // "a"
// Extract<T, U> เลือกเฉพาะค่าที่เป็นทั้ง T และ U
// ในที่นี้ "a" เป็นค่าที่มีทั้งใน "a" | "b" | "c" และ "a" | "f"
NonNullable<T>
(ไม่เป็นค่าว่าง)
ตัด null และ undefined ออกจาก type
ts
type T = NonNullable<string | number | undefined>; // string | number
// NonNullable<T> ตัด null และ undefined ออกจาก type T
// ในที่นี้ตัด undefined ออกจาก string | number | undefined
Parameters<T>
(พารามิเตอร์)
ดึง parameter ของฟังก์ชัน type ออกมาเป็น tuple
ts
function f1(a: number, b: string): void {}
type Params = Parameters<typeof f1>; // [a: number, b: string]
// Parameters<T> ดึง type ของพารามิเตอร์จากฟังก์ชัน T ออกมาเป็น tuple
// ในที่นี้ดึงพารามิเตอร์ของ f1 ออกมาเป็น [number, string]
ReturnType<T>
(ประเภทที่ส่งคืน)
ดึง return type ของฟังก์ชัน type
ts
function f1(): string { return "hi"; }
type R = ReturnType<typeof f1>; // string
// ReturnType<T> ดึง type ของค่าที่ return จากฟังก์ชัน T
// ในที่นี้ f1 return ค่าเป็น string จึงได้ type เป็น string
InstanceType<T>
(ประเภทของอินสแตนซ์)
ดึง type ของ instance ที่ได้จาก constructor
ts
class C { x = 0; }
type T = InstanceType<typeof C>; // C
// InstanceType<T> ดึง type ของ instance ที่ได้จาก constructor T
// ในที่นี้ได้ type เป็น C ซึ่งเป็น type ของ instance ที่สร้างจาก class C