ยูทิลิตี้ไทป์ใน 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 ReadWritePermissions {
3 read: boolean;
4 write: boolean;
5}
6
7const rolePermissions: Record<Roles, ReadWritePermissions> = {
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 userStatus: ExcludedStatus = "active"; // "pending" is excluded, so it cannot be chosen
5console.log(userStatus);- เมื่อใช้
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 userStatus: ActiveStatus = "active"; // "inactive" cannot be chosen
5console.log(userStatus);Extract<T, U>ทำหน้าที่ตรงข้ามกับExcludeในตัวอย่างข้างต้น คุณสามารถเลือกได้เฉพาะ"active"และ"pending"
NonNullable<T>
NonNullable<T> สร้างประเภทที่ไม่มี null และ undefined มีประโยชน์เมื่อคุณต้องการแยกค่าดังกล่าวออกจากประเภทที่ใช้ได้อย่างเลือกได้
1type UserName = string | null | undefined;
2type ValidUserName = NonNullable<UserName>;
3
4const userName: ValidUserName = "Alice"; // null and undefined cannot be chosen
5console.log(userName);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 userName = getProperty(person, "name"); // type is string
7const age = getProperty(person, "age"); // type is number
8
9console.log("Name:", userName);
10console.log("Age:", age);- ฟังก์ชันนี้ดึงคุณสมบัติจากอ็อบเจ็กต์โดยอิงจากคีย์ที่กำหนดในรูปแบบที่ปลอดภัยต่อชนิดข้อมูล
การเพิ่มข้อจำกัดของประเภท
โดยการใช้ 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 ด้วย