# TypeScript Utility Types ### 什麼是 Utility Types? > TypeScript provides several utility types to facilitate common type transformations. 在程式中有時候會撰寫 utils function,透過封裝好的函式將 input 做了些處理並 output 回傳。 在 TS 中也有這些 Type 小工具可以使用,只是 input 為型別,利用這些工具達到「**依據原有的型別,創建新的型別**」。 ## 常見的 Utility Types 用法 ### 1. Partial 將類型 Type 中的所有屬性設置為 optional ``` interface User { name: string; age: number; } function updateUser(user: User, newUser: Partial<User>): void { return [...user, ...newUser] } const user: User = { name: 'Nono', age: 30 }; updateUser(user, { name: 'Alice' }); ``` ### 2. Required 將所有 Type 中的屬性設置為必填,`Partial` 的相反用法 ``` interface User { name?: string; age?: number; } const requiredUser: Required<User> = { name: 'Nono', // Property 'age' is missing in type '{ name: string; }' but required in type 'Required<User>'.(2741) }; ``` ### 3. Readonly 使 Type 中的所有屬性變成唯讀特性,不能夠重新指向賦值 ``` interface Config { apiUrl: string; } function fetchConfig(): Readonly<Config> { return { apiUrl: 'https://api.example.com', }; } const config = fetchConfig(); config.apiUrl = 'https://example.com' // Cannot assign to 'apiUrl' because it is a read-only property.(2540) ``` ### 4. Record `Record<Keys, Type>` 創建物件類型,其屬性 Key 值為 Keys,屬性 Value 為 Type。 此實用程式可用於將一種類型的屬性對應到另一種類型 ``` type Fruit = 'apple' | 'banana' | 'orange'; type Price = number; const fruitPrices: Record<Fruit, Price> = { apple: 20, banana: 10, orange: 15 }; ``` 這邊可以看到前者的 Fruit 型別變成 key 值,後者 Price 型別則是 value 型別 ### 5. Pick `Pick<Type, Keys>` 從 Type 中**選擇**指定的屬性 ``` interface User { name: string; age: number; email: string; } type UserProfile = Pick<User, 'name' | 'email'>; const userDetails: UserProfile = { // 因為僅選擇 name 與 email,所以 age 沒有也可以定義。 name: 'Nono', email: 'Nono@example.com' }; ``` ### 6. Omit `Omit<Type, Keys>`從 Type 中**剔除**指定的屬性 ``` interface User { name: string; age: number; email: string; } type UserProfile = Omit<User, 'email'>; const userProfile: UserProfile = { name: 'Nono', age: 30 }; ``` ### 7. Exclude `Exclude<UnionType, ExcludedMembers>`從 UnionTyp 中剔除可以指派的 union type (差集) ``` type Animal = 'dog' | 'cat' | 'bird' | 'fish'; type Pet = 'dog' | 'cat'; type WildAnimal = Exclude<Animal, Pet>; // 從 Animal type 中排除 Pet,即非寵物的動物,WildAnimal 的Type將是 'bird' | 'fish' ``` ### 8. Extract `Extract<Type, Union>`從 UnionTyp 中提取可以指派的 union type (聯集) ``` type Animal = 'dog' | 'cat' | 'bird' | 'fish'; type Pet = 'dog' | 'cat'; type MyPet = Extract<Animal, Pet>; // 提取 Animal 中屬於 Pet 的部分,MyPet 的 Type 是 'dog' | 'cat' ``` ### Refer: https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers