為什麼要使用Composition API? 根據官方的說法,vue3.0的變化包括性能上的改進、更小的 bundle 體積、對 TypeScript 更好的支持、用於處理大規模用例的全新 API,全新的api指的就是本文主要要說的組合式api。 在 vue3 版本之前,我們復用組件(或者提取和重用 ...
TypeScript中的實用工具類型是一些預定義的泛型類型,可用於操作或創建其它新類型。這些實用工具類型在所有TypeScript項目中都是全局可用的,因此無需添加任務依賴項即可使用它們。
1.Partial<Type>
將Type的所有屬性都設置為可選的類型。
1 interface Person { 2 name: string; 3 age: number; 4 email: string; 5 } 6 7 type PartialPerson = Partial<Person>; 8 9 //相當於 10 // interface Person { 11 // name?: string | undefined; 12 // age?: number | undefined; 13 // email?: string | undefined; 14 // } 15 16 interface Todo { 17 title: string; 18 description: string; 19 } 20 21 function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) { 22 return { ...todo, ...fieldsToUpdate }; 23 } 24 25 const todo1 = { 26 title: "organize desk", 27 description: "clear clutter", 28 }; 29 30 const todo2 = updateTodo(todo1, { 31 description: "throw out trash", 32 });
2.Required<Type>
與Partical<Type> 相反,該類型由Type中所有屬性設置為required組成。
1 interface Person { 2 name?: string | undefined; 3 age?: number | undefined; 4 email?: string | undefined; 5 } 6 7 8 type RequiredPerson = Required<Person>; 9 10 // 相當於 11 // interface Person { 12 // name: string; 13 // age: number; 14 // email: string; 15 // }
3.Omit<Type, Keys>
構建一個新類型--從類型 Type
中獲取所有屬性,然後從中剔除 Keys
屬性。
1 interface User { 2 id: number; 3 name: string; 4 email: string; 5 age: number; 6 } 7 8 type UserWithoutEmail = Omit<User, 'email'>; 9 10 // 相當於 11 // interface Person { 12 // id: string; 13 // name: string; 14 // age: number; 15 // }
也可以移除多個屬性,
1 interface User { 2 id: number; 3 name: string; 4 email: string; 5 age: number; 6 } 7 8 type UserWithoutEmailAndName = Omit<User, 'email' | 'name'>; 9 10 // 相當於 11 // interface Person { 12 // id: string; 13 // age: number; 14 // }
4.Pick<Type, Keys>
從類型 Type
中挑選部分屬性 Keys
來構造類型,與Omit相反。
1 interface User { 2 id: number; 3 name: string; 4 email: string; 5 age: number; 6 } 7 8 type UserWithEmailAndName = Pick<User, 'email' | 'name'>; 9 10 // 相當於 11 // interface Person { 12 // name: string; 13 // email: string; 14 // }
可以組合使用這些類型,創造新的類型
1 interface User { 2 id: number; 3 name: string; 4 email: string; 5 age: number; 6 } 7 8 type PartialPick = Partial<Pick<User, 'email' | 'name'>>; 9 10 // 相當於 11 // interface Person { 12 // name?: string | undefined; 13 // email?: string | undefined; 14 // }
1 interface User { 2 id: number; 3 name: string; 4 email: string; 5 age: number; 6 } 7 8 type OmitPartialPick = Omit<Partial<Pick<User, 'email' | 'name'>>, 'email'>; 9 10 // 相當於 11 // interface Person { 12 // name?: string | undefined; 13 // }
5.Readonly<Type>
通過該Type構造新類型,並將它所有的屬性設置為只讀的,也就意味著構造出的類型的屬性不能被再次賦值。
1 interface Person { 2 id: number; 3 name: string; 4 age: number; 5 } 6 7 type ReadonlyPerson = Readonly<Person>; 8 9 //相當於 10 // interface Person { 11 // readonly id: number; 12 // readonly name: string; 13 // readonly age: number; 14 // } 15 16 const person: ReadonlyPerson = { 17 id: 1, 18 name: 'John', 19 age: 25 20 }; 21 22 person.name = 'Mike'; // Error: Cannot assign to 'name' because it is a read-only property.
這個類型可用來表示在運行時會失敗的賦值表達式(比如,當嘗試給凍結對象的屬性再次賦值時)
Object.freeze
1 function freeze<T>(obj: T): Readonly<T>;
6.Record<Keys, Type>
構造一個對象類型,其屬性為Keys,屬性值為Type;該實用工具類型可用於將一種類型的屬性映射到另一種類型。
1 interface CatInfo { 2 age: number; 3 breed: string; 4 } 5 6 type CatName = "miffy" | "boris" | "mordred"; 7 8 const cats: Record<CatName, CatInfo> = { 9 miffy: { age: 10, breed: "Persian" }, 10 boris: { age: 5, breed: "Maine Coon" }, 11 mordred: { age: 16, breed: "British Shorthair" }, 12 }; 13 14 cats.boris; 15
7.Exclude<UnionType, ExcludedMembers>
通過從 UnionType 中排除所有可分配給 ExcludedMembers 的屬性來構造一個類型;也就是刪除 union 類型的成員來創建新類型。
1 type T0 = Exclude<"a" | "b" | "c", "a">; 2 type T0 = "b" | "c" 3 4 type T1 = Exclude<"a" | "b" | "c", "a" | "b">; 5 type T1 = "c" 6 7 type T2 = Exclude<string | number | (() => void), Function>; 8 type T2 = string | number
8.Extract<Type, Union>
通過從 Type 中提取可分配給 Union 的所有聯合成員來構造一個類型,與 Exclude 相反。
1 type T0 = Extract<"a" | "b" | "c", "a" | "f">; 2 type T0 = "a" 3 4 type T1 = Extract<string | number | (() => void), Function>; 5 type T1 = () => void
9.NonNullable<Type>
通過從 Type 中排除 null 和 undefined 來構造一個類型。
1 type T0 = NonNullable<string | number | undefined>; 2 type T0 = string | number 3 4 type T1 = NonNullable<string[] | null | undefined>; 5 type T1 = string[]
10.ReturnType<Type>
由函數類型 Type
的返回值類型構建一個新類型。
1 function add(a: number, b: number): number { 2 return a + b; 3 } 4 5 type AddReturnType = ReturnType<typeof add>; 6 // type AddReturnType = number; 7 8 9 function addStr(a: string, b: string): string{ 10 return a + b; 11 } 12 13 type AddReturnType2 = ReturnType<typeof addStr>; 14 // type AddReturnType2 = string; 15 16 type T0 = ReturnType<() => string>; 17 type T0 = string 18 19 type T1 = ReturnType<(s: string) => void>; 20 type T1 = void 21 22 type T2 = ReturnType<<T>() => T>; 23 type T2 = unknown 24 25 type T3 = ReturnType<<T extends U, U extends number[]>() => T>; 26 type T3 = number[]
11.Parameters<Type>
由函數類型 Type
的參數類型來構建出一個元組類型。
1 function add(a: number, b: string, c:boolean): string { 2 return a + b; 3 } 4 5 type AddReturnType = Parameters<typeof add>; 6 // type AddReturnType = [a: number, b: string, c:boolean]; 7 8 type T0 = Parameters<() => string>; 9 type T0 = [] 10 11 type T1 = Parameters<(s: string) => void>; 12 type T1 = [s: string] 13 14 type T2 = Parameters<<T>(arg: T) => T>; 15 type T2 = [arg: unknown]
12.Awaited<Type>
這種類型旨在模擬非同步函數中的 await 或 Promises 上的 .then() 方法等操作——具體來說,就是它們遞歸展開 Promises 的方式。
1 async function fetchData(): Promise<string> { 2 // fetch data from API and return a string 3 } 4 5 type ResolvedResult = Awaited<ReturnType<typeof fetchData>>; 6 // type ResolvedResult = string 7 8 type A = Awaited<Promise<string>>; 9 type A = string 10 11 type B = Awaited<Promise<Promise<number>>>; 12 type B = number 13 14 type C = Awaited<boolean | Promise<number>>; 15 type C = number | boolean
以上,是較常用的一些實用工具類型。
參考資料:
https://www.typescriptlang.org/docs/handbook/utility-types.html#uppercasestringtype
https://dev.to/arafat4693/typescript-utility-types-that-you-must-know-4m6k