您好,登錄后才能下訂單哦!
這篇文章主要介紹“TypeScript內置工具類型怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“TypeScript內置工具類型怎么使用”文章能幫助大家解決問題。
TypeScript 附帶了大量類型,可以幫助進行一些常見的類型操作,通常稱為 Utility Types。
將必填參數變為可選參數
namespace a { // 示例一: interface A { name: string, age: number, sex: string } // 接口A中的參數通過內置工具類型Partial變成了可選參數 type PartialA = Partial<A>; let a: PartialA = { // 此處傳參可以任意個數,但只能傳已定義的參數 name: '張三', age: 10 } // 示例二: interface Company { id: number, name: string } interface Person { id: number, name: string, company: Company } // 實現DeepPartial,將參數深度轉換成可選參數 type DeepPartial<T> = { [U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U]; } type PartialPerson = DeepPartial<Person>; let p: PartialPerson = { // 此處的參數已經變為可選參數,可根據自己需要傳遞 id: 10, name: '張三', company: { name: '美團' } } }
Partial的實現源碼
namespace b { interface A { name: string, age: number, sex: string } type Partial<T> = { // 原理: // 1.通過keyof拿到T中的所有key // 2.迭代所有的key // 3.統一加上可選參數處理 // 4.返回迭代值的類型 [P in keyof T]?: T[P]; } // 測試: type PartialA = Partial<A>; let a: PartialA = { name: '張三', age: 10 } }
將所有參數變為必填
namespace b { interface Person { name: string, age?: number } // Required將可選參數變為必填 type RequiredPerson = Required<Person>; let person: RequiredPerson = { name: '張三', age: 10 } }
Required 的實現源碼
namespace c { interface Person { name: string, age?: number } type Required<T> = { // 原理: // 1.通過keyof拿到T中所有的key // 2.迭代所有的key // 3.將可選的參數變為必填的參數 // 4.返回迭代屬性及類型 // +?或者?: 代表的是可選,-?: 代表的是不可選 [P in keyof T]-?: T[P]; }; // 測試 type RequiredPerson = Required<Person>; let person: RequiredPerson = { name: '李四', age: 18 } }
將所有參數變為只讀
namespace d { interface Person { name: string, age?: number } type ReadonlyPerson = Readonly<Person>; let person: ReadonlyPerson = { name: '張三', age: 10 } // 已經變為只讀屬性,因此此處賦值會報錯 // person.name = '李四'; // 無法分配到 "name" ,因為它是只讀屬性。ts(2540) // person.age = 20; // 無法分配到 "age" ,因為它是只讀屬性。ts(2540) }
Readonly 的實現源碼
namespace e { interface Person { name: string, age?: number } type Readonly<T> = { // 原理: // 1.通過keyof拿到T中所有key // 2.迭代拿到的所有key // 3.通過readonly關鍵字將所有屬性變為只讀屬性 // 4.返回迭代屬性及類型 readonly [P in keyof T]: T[P] } // 測試 type ReadonlyPerson = Readonly<Person>; let person: ReadonlyPerson = { name: '張三', age: 10 } // person.name = '李四'; // 無法分配到 "name" ,因為它是只讀屬性。ts(2540) // person.age = 20; // 無法分配到 "age" ,因為它是只讀屬性。ts(2540) }
撿取符合條件的屬性
namespace g { interface Person { name: string, age: number, sex: string } // 參數一是一個對象,參數二是要篩選的屬性 type PickPerson = Pick<Person, 'name' | 'sex'>; let person: PickPerson = { name: '張三', // 由于通過Pick只撿取了name和sex屬性,因此此時給sex賦值會報錯 // 不能將類型“{ name: string; age: number; sex: string; }”分配給類型“PickPerson”。 // 對象文字可以只指定已知屬性,并且“age”不在類型“PickPerson”中。ts(2322) // age: 10, sex: '男' } }
Pick 的實現源碼
namespace h { interface Person { name: string, age: number, sex: string } // 原理: // 1.T表示傳入的類型定義。此處指Person接口。 // 2.K表示T的子類型,是一個聯合類型。此處指'name' | 'age' | 'sex'的子類型 // 3.通過keyof拿到T中的所有key // 3.迭代K,拿到所有傳遞進來的子類型 // 4.返回迭代屬性及類型 // 簡單理解:就是從一個對象中,提取一部分屬性組成新的對象 type Pick<T, K extends keyof T> = { [P in K]: T[P]; } // 測試 type PickPerson = Pick<Person, 'name' | 'age'> let person: PickPerson = { name: '張三', age: 10 } }
記錄類型:將一個類型的所有屬性值都映射到另一個屬性上并創建新的類型
namespace i { // 1.此處的K主要用來修飾obj對象的key,為string或者number // 2.此處的T用來修飾老的類型 // 3.此處的U用來修飾新的類型 function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) { // 聲明一個變量 let result: Record<K, U> = <Record<K, U>>{}; // 遍歷傳入的對象 for (const key in obj) { // 通過callback函數處理result的屬性值 result[key] = callable(obj[key]); } // 返回result return result; } let obj = { num1: 1, num2: 2 }; let callable = (x: number): string => x * 2 + ''; let newObj = mapObj<string | number, number, string>(obj, callable); console.log(newObj); // { num1: '2', num2: '4' } }
Record 的實現源碼
namespace j { type Record<K extends keyof any, T> = { // 原理: // 1.通過keyof拿到所有的K,是一個聯合類型。string | number | symbol // 2.迭代K,拿到所有的屬性 // 3.返回迭代的屬性及類型 // 注意:此處不能寫成 type Record<K, T> = {}; any代表所有key的聯合類型。 // 否則會報錯:不能將類型“K”分配給類型“string | number | symbol”。ts(2322) [P in K]: T; }; // 測試 function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) { // 聲明一個變量 let result: Record<K, U> = <Record<K, U>>{}; // 遍歷傳入的對象 for (const key in obj) { // 通過callback函數處理result的屬性值 result[key] = callable(obj[key]); } // 返回result return result; } let obj = { num1: 1, num2: 2 }; let callable = (x: number): string => x * 2 + ''; let newObj = mapObj<string | number, number, string>(obj, callable); console.log(newObj); // { num1: '2', num2: '4' } }
關于“TypeScript內置工具類型怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。