工具型別
工具型別(Utility Types)是 TypeScript 內建、不用自己實作的型別轉換工具,用來從既有的型別「衍生」出新型別,避免同一份欄位定義在專案裡複製貼上好幾遍。
先假設有這個基礎型別:
Partial:全部變可選
function updateUser(id: number, changes: Partial<User>) {
// changes 可能只包含 User 的部分欄位
}
updateUser(1, { name: "New Name" }) // 不用整個 User 物件也合法
更新表單、PATCH API 這類「只改一部分欄位」的情境很常用,不用另外手寫一個所有欄位都是可選的 interface。
Required:全部變必要
跟 Partial 相反,用在「這裡不允許任何欄位缺漏」的情境。
Pick 與 Omit:挑欄位、去欄位
type UserPreview = Pick<User, "id" | "name"> // 只留 id、name
type UserWithoutEmail = Omit<User, "email"> // 留除了 email 以外的全部
列表頁、卡片元件通常只需要完整資料的一部分,Pick 明確列出要留哪些欄位;Omit 反過來,列出要排除哪些欄位,適合欄位很多、只想排除一兩個的情況。
Record:建立「鍵值對」型別
type UserId = number
type UserMap = Record<UserId, User>
const users: UserMap = {
1: { id: 1, name: "Alice", email: "a@example.com", age: 20 },
2: { id: 2, name: "Bob", email: "b@example.com", age: 25 },
}
Record<鍵的型別, 值的型別> 比手寫 { [key: number]: User } 更直觀,常用在把陣列資料轉成以 id 查找的物件時。
Readonly:整個物件變唯讀
const config: Readonly<{ apiUrl: string }> = { apiUrl: "https://api.example.com" }
// config.apiUrl = "other" // 編譯錯誤
用在設定值、常數這類建立後不該再被修改的物件。
相關資源
這幾個工具型別彼此常常合併使用(例如 Partial<Pick<User, "name" | "age">>),完整清單與更進階的 Extract、Exclude、ReturnType 等,請看 官方 Utility Types 參考;Total TypeScript 由核心貢獻者 Matt Pocock 製作的免費練習題,有專門一節互動示範這些工具型別怎麼組合使用。