ยูทิลิตี้ไทป์ใน TypeScript

ยูทิลิตี้ไทป์ใน 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"

ตัวอย่างการใช้งาน

  1. การใช้ในอาร์กิวเมนต์ของฟังก์ชัน

    คุณสามารถใช้ 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
  1. การเพิ่มข้อจำกัดของประเภท

    โดยการใช้ 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 ด้วย

YouTube Video