iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
JavaScript

我推的TypeScript 操作大全系列 第 22

我推Day22 - TypeScript 神器現身:實用型別讓你的程式碼升級成超能力

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241006/20124462KTmrxL9Efz.jpg


TypeScript 實用工具型別進階解析:Unlock Hidden Superpowers

在 TypeScript 中,有一組強大的內建工具型別(Utility Types),除了上次介紹的之外,還有能讓你的程式碼更簡潔、更具可讀性,還能幫助你避免一些難以察覺的錯誤!

今天,我將分享幾個不那麼常見但超有用的工具型別,幫助你在專案開發中事半功倍。
準備好來探索 TypeScript 的隱藏超能力了嗎?讓我們開始吧!🚀


好的!我來幫你進行更詳細的說明和修飾這兩段內容。


1. Awaited 進階應用:掌握異步操作的強力助手 🌟

Awaited 型別專門用來推斷 Promise 的結果,這在處理異步操作時特別有用。通常情況下,當 TypeScript 無法自動推斷函式的返回型別時,使用 Awaited 可以讓我們明確指定預期的資料結構,提升程式碼的安全性與可靠性。

範例

// 一個模擬的異步操作,從 API 中獲取代辦事項
async function fetchTodoItem() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  return await response.json();
}

// 定義待辦事項的型別結構
type TodoItem = {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

// 使用 `Awaited` 來推斷異步操作的返回值型別
async function displayTodoItem() {
  const todo: Awaited<TodoItem> = await fetchTodoItem();
  console.log(`Todo: ${todo.title}`);
}

說明

  • 在這個例子中,Awaited 型別允許我們確保 fetchTodoItem 返回的 Promise 結果符合我們預期的 TodoItem 型別結構。這樣做不僅讓程式碼更具型別安全性,還能在處理異步資料時避免不必要的錯誤。
  • 當我們從 API 或其他非靜態類型的資料源獲取資料時,TypeScript 無法直接推斷回傳結果的具體型別。此時,Awaited 就派上用場,幫助我們手動指定這些異步資料的型別結構。

應用場景

Awaited 對於需要處理異步操作的專案尤其重要,特別是在需要與外部 API 互動或處理大量非同步邏輯時。它確保了異步回傳結果的型別正確性,避免了因資料結構不一致而導致的程式錯誤,讓開發者在操作異步資料時更有信心。


2. Record<K, T>:動態鍵與固定型別的完美搭配 💡

Record<K, T> 是 TypeScript 中用來建立具有特定鍵值型別與對應值型別的物件型別工具。這種結構特別適合需要對特定鍵賦予特定型別的應用場景,像是權限管理、資料映射或查詢表等,能有效地確保物件的結構與型別一致性。

範例

// 定義使用者角色
type Role = 'admin' | 'editor' | 'viewer';

// 定義權限結構
type Permission = { canRead: boolean; canWrite: boolean };

// 使用 `Record<K, T>` 為每個角色分配對應的權限
const rolePermissions: Record<Role, Permission> = {
  admin: { canRead: true, canWrite: true },
  editor: { canRead: true, canWrite: false },
  viewer: { canRead: true, canWrite: false }
};

// 檢查某個角色是否具備特定權限
function hasPermission(role: Role, action: keyof Permission): boolean {
  return rolePermissions[role][action];
}

console.log(hasPermission('admin', 'canWrite')); // true

說明

  • Record<K, T> 是 TypeScript 中的強力工具,它允許你建立一個特定鍵值(K)和對應型別(T)的物件。舉例來說,我們在範例中定義了三個角色(admineditorviewer),並為每個角色指定了對應的權限(Permission)。這樣一來,我們就可以確保每個角色的權限結構都是一致且正確的。
  • 函式 hasPermission 使用 keyof Permission 來檢查角色是否具備特定的權限,這不僅讓程式碼更具結構性,還大大減少了手動操作錯誤的可能性。

應用場景

Record<K, T> 特別適合處理固定鍵值但需對應不同資料型別的應用場景,例如角色權限系統、設定檔案或查詢表等。這個工具型別能確保物件中的每個鍵都有明確且一致的型別限制,減少手動錯誤的機會並提升程式碼的維護性。


3. keyof:取物件型別的鍵值

keyof 是 TypeScript 中的一個強大運算子,能夠從一個物件型別中提取出鍵名,這對於確保函式的參數符合物件的鍵名時非常有用。讓我們來看一個範例。

範例

type User = {
  id: number;
  name: string;
  email: string;
};

// 定義一個接受 `User` 型別的鍵值的函式
function getUserProperty(key: keyof User): string {
  const user: User = {
    id: 1,
    name: 'Mr Smith',
    email: 'mrsmith@example.com',
  };

  // 這裡我們假設所有屬性都能被轉換成字串
  return String(user[key]);
}

// 正確的使用
const userName = getUserProperty('name'); // 'name' 是 User 的鍵值
console.log(userName);

// 錯誤的使用,TypeScript 會報錯
// const userCountry = getUserProperty('country'); 
// Argument of type '"country"' is not assignable to parameter of type 'keyof User'.

說明

  • keyof 會提取 User 型別中的所有鍵,並將它們組合成一個聯合型別 'id' | 'name' | 'email'。這樣我們就可以確保傳遞給 getUserProperty 函式的參數必須是 User 中的合法鍵名。

應用場景

keyof 非常適合用於確保物件屬性名稱的正確性,特別是在動態存取物件屬性時。這樣可以避免手動輸入錯誤的鍵名,讓程式碼更加穩健。


4. ReturnType:提取函式的回傳型別

ReturnType 是另一個實用的工具型別,它能幫助你推斷函式的回傳型別。這對於確保後續操作符合函式的返回結果時特別有幫助。

範例

// 定義一個回傳設定物件的函式
function loadAppConfig() {
  return {
    apiUrl: 'https://api.example.com',
    retryAttempts: 5,
    debugMode: false,
  };
}

// 使用 `ReturnType` 推斷回傳物件的型別
type AppConfig = ReturnType<typeof loadAppConfig>;

// 現在我們可以在其他地方安全地使用 `AppConfig` 型別
function setupApi(config: AppConfig) {
  console.log(`API URL: ${config.apiUrl}`);
  console.log(`Retry Attempts: ${config.retryAttempts}`);
  console.log(`Debug Mode: ${config.debugMode ? 'Enabled' : 'Disabled'}`);
}

const config = loadAppConfig();
setupApi(config);

說明

  • ReturnType 運用了 TypeScript 的推斷能力,從 loadAppConfig 函式自動推斷出它的回傳值型別,並且賦值給 AppConfig 型別。這讓我們在使用這些返回值時能夠保證型別安全,不用手動重複定義型別。

應用場景

ReturnType 特別適合用在有多個函式共享同一回傳型別的情況。透過 ReturnType,你可以避免手動定義重複型別,並確保所有使用這些回傳值的地方都符合同一個型別。


總結

  • keyof:幫助我們從物件型別中提取鍵名,確保存取物件屬性時能夠安全地操作,避免輸入錯誤的鍵名。

  • ReturnType:能夠從函式中自動推斷出回傳值型別,讓後續使用該函式的回傳值時能夠更加安全和一致。

  • Awaited:幫助你推斷 Promise 的結果型別,特別適合處理複雜的異步操作時使用,確保資料結構的正確性。

  • Record<K, T>:允許你建立具有特定鍵和值型別的物件,特別適合處理角色權限、查詢表等需要嚴格定義鍵值對的情境。

這些型別讓你的 TypeScript 程式碼更具結構性和型別安全性,有效減少大型專案中的潛在錯誤,讓開發過程輕鬆愉快。

靈活運用這些工具型別,能幫助你寫出更穩健、可維護的程式碼,讓 TypeScript 的開發更加得心應手!💪

結論

工具型別不僅能讓程式碼更加精確,還能幫助你避免隱藏的錯誤。
TypeScript 的工具型別大大提升了開發效率和生產力,讓你的專案開發既高效又充滿樂趣!🌟


上一篇
我推Day21 - 解鎖 TypeScript 潛力:7 大實用型別讓你程式碼飛起來!
下一篇
我推Day23 - 超強 TypeScript 陣列方法解析:讓你事半功倍的 6 大終極技巧!
系列文
我推的TypeScript 操作大全30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言