ยูทิลิตี้ไทป์ใน TypeScript
บทความนี้อธิบายยูทิลิตี้ไทป์ใน TypeScript
YouTube Video
ยูทิลิตี้ไทป์ใน TypeScript
ยูทิลิตี้ไทป์ใน TypeScript เป็นเครื่องมือที่สะดวกสำหรับการสร้างไทป์ใหม่บนพื้นฐานจากไทป์ที่มีอยู่ สิ่งนี้ช่วยให้สามารถกำหนดไทป์ได้ยืดหยุ่นมากขึ้นและเพิ่มความสามารถในการนำโค้ดกลับมาใช้ใหม่ ที่นี่เราจะอธิบายยูทิลิตี้ไทป์ที่ใช้บ่อยโดยละเอียดและแสดงวิธีการใช้งานแต่ละแบบพร้อมโค้ดตัวอย่าง
Partial<T>
Partial<T>
ทำให้ทุกคุณสมบัติในไทป์ของออบเจ็กต์กลายเป็นตัวเลือกทั้งหมด (อนุญาตให้มี undefined
) สิ่งนี้มีประโยชน์เมื่อคุณต้องการใช้เพียงบางคุณสมบัติของไทป์ดั้งเดิม
1interface User {
2 id: number;
3 name: string;
4 age: number;
5}
6
7function updateUser(user: Partial<User>) {
8 console.log(user);
9}
10
11updateUser({ name: "Alice" }); // Updates only 'name'
คำอธิบาย:
จากตัวอย่างข้างต้น การใช้ Partial<User>
ทำให้ทุกคุณสมบัติของไทป์ User
เป็นตัวเลือกได้ ดังนั้น ในฟังก์ชัน updateUser
คุณสามารถส่งข้อมูลเพียงบางส่วนของคุณสมบัติได้
Required<T>
Required<T>
ทำให้ทุกคุณสมบัติ รวมถึงที่เป็นตัวเลือก กลายเป็นสิ่งที่จำเป็นทั้งหมด มันถูกใช้เมื่อคุณต้องการเปลี่ยนคุณสมบัติที่เป็นตัวเลือกให้กลายเป็นสิ่งที่จำเป็น
1interface User {
2 id: number;
3 name?: string;
4 age?: number;
5}
6
7function createUser(user: Required<User>) {
8 console.log(user);
9}
10
11// createUser({ id: 1 }); // Error: 'name' and 'age' are required
12createUser({ id: 1, name: "Alice", age: 25 });
คำอธิบาย:
โดยการใช้ Required<User>
คุณสมบัติเช่น name
และ age
จะถูกทำให้กลายเป็นสิ่งที่จำเป็น
Readonly<T>
Readonly<T>
ทำให้คุณสมบัติทั้งหมดในออบเจ็กต์เป็นแบบอ่านอย่างเดียว สิ่งนี้ช่วยป้องกันไม่ให้ค่าของออบเจ็กต์ถูกเปลี่ยนแปลง
1interface User {
2 id: number;
3 name: string;
4}
5
6const user: Readonly<User> = {
7 id: 1,
8 name: "Alice"
9};
10
11// user.id = 2; // Error: 'id' is read-only
12console.log(user);
คำอธิบาย:
โดยการใช้ Readonly<T>
คุณสามารถป้องกันไม่ให้คุณสมบัติของออบเจ็กต์ถูกเปลี่ยนแปลงได้ สิ่งนี้มีประสิทธิภาพเมื่อคุณต้องการป้องกันข้อมูลไม่ให้ถูกเปลี่ยนแปลงโดยไม่ได้ตั้งใจระหว่างการพัฒนา
Record<K, T>
Record<K, T>
สร้างไทป์ของแผนที่ที่มีไทป์คีย์และค่าแบบที่ถูกกำหนดไว้ K
คือไทป์สำหรับคีย์ (เช่น string
หรือ number
) และ T
คือไทป์สำหรับค่าต่าง ๆ
1type Roles = "admin" | "user" | "guest";
2interface Permissions {
3 read: boolean;
4 write: boolean;
5}
6
7const rolePermissions: Record<Roles, Permissions> = {
8 admin: { read: true, write: true },
9 user: { read: true, write: false },
10 guest: { read: false, write: false },
11};
12
13console.log(rolePermissions);
คำอธิบาย:
Record<K, T>
มีประโยชน์เมื่อคุณต้องการกำหนดคู่คีย์และค่า ในตัวอย่างข้างต้น สิทธิถูกกำหนดขึ้นตามบทบาทของผู้ใช้
Pick<T, K>
Pick<T, K>
ดึงเฉพาะคุณสมบัติที่ระบุจากไทป์ของออบเจ็กต์ คุณสามารถสร้างไทป์ใหม่โดยการดึงเฉพาะคุณสมบัติที่จำเป็น
1interface User {
2 id: number;
3 name: string;
4 age: number;
5}
6
7type UserSummary = Pick<User, "id" | "name">;
8
9const summary: UserSummary = {
10 id: 1,
11 name: "Alice"
12};
13
14console.log(summary);
คำอธิบาย:
โดยการใช้ Pick<T, K>
คุณสามารถดึงคุณสมบัติเฉพาะจากไทป์ของออบเจ็กต์และนำไปใช้เป็นไทป์ใหม่ได้ ตัวอย่างเช่น เฉพาะ id
และ name
ที่ถูกดึงออกมาในตัวอย่างข้างต้น
Omit<T, K>
Omit<T, K>
ใช้สำหรับแยกคุณสมบัติเฉพาะออกจากประเภทของวัตถุ นี่คือกระบวนการที่ตรงข้ามกับ Pick
1interface User {
2 id: number;
3 name: string;
4 age: number;
5 email: string;
6}
7
8type UserWithoutEmail = Omit<User, "email">;
9
10const userWithoutEmail: UserWithoutEmail = {
11 id: 1,
12 name: "Alice",
13 age: 25
14};
15
16console.log(userWithoutEmail);
คำอธิบาย:
การใช้ Omit<T, K>
คุณสามารถสร้างประเภทใหม่โดยแยกคุณสมบัติเฉพาะออก จากตัวอย่างข้างต้น คุณสมบัติ email
ถูกแยกออก
Exclude<T, U>
Exclude<T, U>
ใช้สร้างประเภทใหม่โดยลบประเภท U
ออกจากประเภท union T
ใช้เมื่อคุณต้องการลบประเภทที่เฉพาะเจาะจง
1type Status = "active" | "inactive" | "pending";
2type ExcludedStatus = Exclude<Status, "pending">;
3
4const status: ExcludedStatus = "active"; // "pending" is excluded, so it cannot be chosen
5console.log(status);
คำอธิบาย:
เมื่อใช้ Exclude<T, U>
คุณสามารถลบประเภทที่ไม่จำเป็นในประเภท union ได้ ในตัวอย่างข้างต้น เนื่องจาก "pending"
ถูกแยกออก คุณสามารถเลือกได้เฉพาะ "active"
หรือ "inactive"
เท่านั้น
Extract<T, U>
Extract<T, U>
ใช้สำหรับดึงส่วนที่ตรงกับประเภท U
ในประเภท union T
มีประโยชน์เมื่อคุณต้องการดึงเฉพาะประเภทที่เฉพาะเจาะจง
1type Status = "active" | "inactive" | "pending";
2type ActiveStatus = Extract<Status, "active" | "pending">;
3
4const status: ActiveStatus = "active"; // "inactive" cannot be chosen
5console.log(status);
คำอธิบาย:
Extract<T, U>
ทำหน้าที่ตรงข้ามกับ Exclude
ในตัวอย่างข้างต้น คุณสามารถเลือกได้เฉพาะ "active"
และ "pending"
NonNullable<T>
NonNullable<T>
สร้างประเภทที่ไม่มี null
และ undefined
มีประโยชน์เมื่อคุณต้องการแยกค่าดังกล่าวออกจากประเภทที่ใช้ได้อย่างเลือกได้
1type UserName = string | null | undefined;
2type ValidUserName = NonNullable<UserName>;
3
4const name: ValidUserName = "Alice"; // null and undefined cannot be chosen
5console.log(name);
คำอธิบาย:
NonNullable<T>
แยก null
และ undefined
ออกจากประเภทที่มีค่าดังกล่าว สิ่งนี้มีประโยชน์เมื่อคุณต้องการให้แน่ใจว่าค่ามีอยู่จริง
สรุป
ประเภท utility ใน TypeScript เป็นเครื่องมือที่ทรงพลังสำหรับทำให้การกำหนดประเภทมีความกระชับและยืดหยุ่นมากขึ้น การเข้าใจและใช้งานประเภท utility พื้นฐาน เช่น Partial
, Required
, Readonly
, Record
อย่างเหมาะสม สามารถเพิ่มความสามารถในการนำโค้ดกลับมาใช้ใหม่และการบำรุงรักษาได้ การเชี่ยวชาญในประเภทเหล่านี้ช่วยให้คุณสามารถกำหนดประเภทที่ปลอดภัยและแข็งแรงมากขึ้น ทำให้การพัฒนาโค้ดมีประสิทธิภาพมากขึ้น
ตัวดำเนินการ keyof
ใน TypeScript
ตัวดำเนินการ keyof
ใน TypeScript ใช้เพื่อดึงชื่อคุณสมบัติทั้งหมดของประเภทวัตถุ ด้วยตัวดำเนินการนี้ คุณสามารถดึงคีย์ของประเภทอ็อบเจกต์เป็นประเภทสหภาพได้ นี่เป็นประโยชน์อย่างยิ่งสำหรับการเขียนโค้ดที่ปลอดภัยต่อประเภท
การใช้งานพื้นฐาน
1interface Person {
2 name: string;
3 age: number;
4 email: string;
5}
6
7// Use keyof to get the property names of Person
8type PersonKeys = keyof Person; // "name" | "age" | "email"
ตัวอย่างการใช้งาน
-
การใช้ในอาร์กิวเมนต์ของฟังก์ชัน
คุณสามารถใช้
keyof
เพื่อกำหนดฟังก์ชันที่มีประเภทตามคุณสมบัติเฉพาะของอ็อบเจกต์
1function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
2 return obj[key];
3}
4
5const person: Person = { name: "Alice", age: 30, email: "alice@example.com" };
6const name = getProperty(person, "name"); // type is string
7const age = getProperty(person, "age"); // type is number
-
การเพิ่มข้อจำกัดของประเภท
โดยการใช้
keyof
คุณสามารถมั่นใจได้ว่าคีย์ที่ส่งไปยังฟังก์ชันนั้นถูกตรวจสอบในช่วงเวลาคอมไพล์
1// Passing an invalid property name results in an error
2const invalid = getProperty(person, "invalidKey"); // Error
สรุป
- ตัวดำเนินการ
keyof
ใช้ในการดึงชื่อคุณสมบัติทั้งหมดของประเภทอ็อบเจกต์ - คุณสามารถดึงชื่อคุณสมบัติเป็นประเภทสหภาพ เพื่อให้ได้โค้ดที่ปลอดภัยต่อประเภท
- โดยใช้ในอาร์กิวเมนต์ของฟังก์ชัน คุณสามารถจำกัดให้ฟังก์ชันรับเฉพาะชื่อคุณสมบัติที่ถูกต้องเท่านั้น
ด้วยวิธีนี้ ตัวดำเนินการ keyof
ช่วยเพิ่มความปลอดภัยของประเภทใน TypeScript และช่วยให้คุณเขียนโค้ดที่มีความทนทานมากขึ้น
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย