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> 通過從聯合型別 T 中移除型別 U 來創建新的型別。當你想要移除特定型別時可以使用它。
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>,你可以從聯合型別中移除不必要的型別。在上述範例中,由於"pending"被排除,僅能選擇"active"或"inactive"。
Extract<T, U>
Extract<T, U> 從聯合型別 T 中提取符合型別 U 的部分。當你想要僅提取特定型別時,這非常有用。
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,確保值一定存在。
結論
TypeScript 的工具型別是使型別定義更簡潔且更靈活的強大工具。了解並適當使用像是 Partial、Required、Readonly、Record 等基礎工具型別,可以提升程式碼的重用性與可維護性。掌握這些型別可以實現更強健且安全的型別定義,從而促進高效開發。
TypeScript 的 keyof 運算子
TypeScript 的 keyof 運算子用於取得物件型別的所有屬性名稱。使用此運算符,您可以將物件類型的鍵作為聯合類型來獲取。這對於編寫類型安全的程式碼非常有用。
基本用法
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 中的類型安全性,幫助您編寫更穩健的程式碼。
您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。