TypeScript 工具泛型教程示例
前言
Typescript 中默認內(nèi)置了很多工具泛型,通過使用這些工具,可以使得我們定義類型更加靈活,高效。本文將會介紹常用泛型工具的使用技巧,以及對其實現(xiàn)原理進行相應的解析,如果有錯誤的地方,還望指出。
Partial\<T>
作用:將傳入對象類型 T 的屬性變?yōu)?strong>可選屬性。
示例:
interface Person {
name: string;
age: number;
}
const tom: Partial<Person> = {
name: "Tom",
};javascript:void(0)Partial<Person> 等價于
interface Person {
name?: string;
age?: number;
}實現(xiàn)原理:
- 通過關鍵字
keyof將傳入對象類型的鍵值轉換為聯(lián)合類型。 - 通過關鍵字
in遍歷聯(lián)合類型,即遍歷對象的鍵值。 - 通過類型映射,將對象的屬性轉換為可選屬性
type MyPartial<T> = {
[P in keyof T]?: T[P];
};Readonly\<T>
作用:把傳入對象類型 T 屬性變?yōu)?strong>只讀屬性。
示例:
interface Person {
name: string;
age: number;
}
const tom: Readonly<Person> = {
name: "Tom",
age: 18;
};
tom.age = 22 // errorReadonly<Person> 等價于
interface Person {
readonly name: string;
readonly age: number;
}實現(xiàn)原理:
與Partial類似:
- 通過關鍵字
keyof將傳入對象類型的鍵值轉換為聯(lián)合類型。 - 通過關鍵字
in遍歷聯(lián)合類型,即遍歷對象的鍵值。 - 通過類型映射,將對象的屬性轉換為只讀屬性
type Readonly<T> = {
[P in keyof T]-?: T[P];
};Required\<T>
作用:把傳入對象類型 T 屬性變?yōu)?strong>必填屬性。
示例:
interface Person {
name?: string;
age?: number;
}
let tom: Required<Person>
tom = {
name: "Tom",
age: 18;
};
// ok
tom = {
name: "Tom",
};
// error實現(xiàn)原理:
與Partial類似:
- 通過關鍵字
keyof將傳入對象的鍵值轉換為枚舉類型。 - 通過關鍵字
in遍歷枚舉類型,即遍歷對象的鍵值。 - 通過類型映射,再統(tǒng)一通過
-?修飾符移除?修飾符,從而轉變?yōu)?strong>必填狀態(tài)。
type Required<T> = {
Required [P in keyof T]: T[P];
};Record\<K,T>
作用:它用來生成一個屬性名為 K,屬性值類型為 T 的對象類型集合。
示例:
// 快速生成一個 Person 對象
type Person = Record<"name" | "country", string>;
const Tom: Person = { name: "Tom", country: "America" };實現(xiàn)原理:
- 通過
K extends keyof any對K參數(shù)進行約束,將其約束為任意類型any的鍵值。 - 通過
in對鍵值集合K進行遍歷,然后生成類型為T的鍵值對集合。
type MyRecord<K extends keyof any, T> = {
[P in K]: T;
};Exclude\<T,K>
作用:從類型 T 中排除所有可以賦值給類型 U 的類型。
示例:
// 從 "a" | "b" | "c" 中排除掉 "a" 類型 type T1 = Exclude<"a" | "b" | "c", "a">; // T1 = "b" | "c" // 從 string | number | boolean 中排除掉 string 類型 type T2 = Exclude<string | number | boolean, string>; // T2 = number | boolean
實現(xiàn)原理:
通過條件類型
T extends U ? never : T對T參數(shù)進行判別:- 如果
T可賦值給U,那么返回never(即排除掉T)。 - 如果
T不可賦值給U,那么返回T。
- 如果
- 通過分布式條件類型,如果
T為聯(lián)合類型,則將條件類型的結果分發(fā)為聯(lián)合類型。
type Exclude<T, U> = T extends U ? never : T;
Extract\<T,K>
作用:與 Exclude 相反,從類型 T 中提取所有可以賦值給類型 U 的類型。
示例:
// 從 "a" | "b" | "c" 中提取出 "a" 類型 type T1 = Extract<"a" | "b" | "c", "a">; // T1 = "a" // 從 string | number | boolean 中提取出 string 類型 type T2 = Extract<string | number | boolean, string>; // T2 = string type T3 = Extract<string | (() => void), Function>; // 相當于 type T3 = () => void;
實現(xiàn)原理:
與 Exclude 類似:
通過條件類型
T extends U ? never : T對T參數(shù)進行判別:- 如果
T可賦值給U,那么返回T。 - 如果
T不可賦值給U,那么返回never(即排除掉T)。
- 如果
- 通過分布式條件類型,如果
T為聯(lián)合類型,則將條件類型的結果分發(fā)為聯(lián)合類型。
type Extract<T, U> = T extends U ? T : never;
Pick\<T,K>
作用:在 T 中,摘選出 K 屬性。
示例:
interface Person {
name: string;
age: number;
}
// 從 Person 中摘選出 name 屬性
type PickPerson = Pick<Person, "name">;
const tom: PickPerson = {
name: "Tom",
};實現(xiàn)原理:
- 通過
K extends keyof T對K參數(shù)進行約束,將其約束為T的鍵值范圍內(nèi)。 - 通過
in對鍵值集合K進行遍歷,然后生成類型為T的鍵值對集合。
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};Omit\<T,K>
作用:在 T 中,剔除掉 K 屬性。
示例:
interface Person {
name: string;
age: number;
}
// 從 Person 中剔除掉 name 屬性
type OmitPerson = Omit<Person, "name">;
const tom: OmitPerson = {
age: 18,
};實現(xiàn)原理:
- 通過
K extends keyof T對K參數(shù)進行約束,將其約束為T的鍵值范圍內(nèi)。 - 通過
Exclude<keyof T, K>將類型集合T中的K類型排除掉。 - 通過
Pick<T,Exclude<keyof T, K>>在T中摘選出排除掉K的T的屬性。
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
ReturnType\<T>
作用:獲取函數(shù)的返回值類型。
示例:
type Fun = () => string;
// 獲取 Fun 返回值的類型
type T1 = ReturnType<Fun>; // T1 = string
type T2 = ReturnType<() => { x: number; y: number }>;
// T2 = { x: number, y: number }實現(xiàn)原理:
- 通過
extends對T參數(shù)進行約束,(...args: any) => any表示一個函數(shù)類型,即T參數(shù)的類型必須是一個函數(shù)類型。 T extends U ? X : Y是條件類型(注意和之前表示約束的extends做區(qū)分),其中T是泛型參數(shù),U是條件部分,X是符合條件的返回結果,Y是不符合條件的返回結果。- 推斷類型
infer的作用是:在條件類型內(nèi)部聲明一個類型變量。(...args: any) => infer R是條件類型的條件部分,它聲明了一個類型變量R,用來存儲函數(shù)的返回類型。 T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any表示:- 如果
T是函數(shù)類型((...args: any) => infer R),則返回R, 即函數(shù)的返回類型。 - 如果
T不是函數(shù)類型((...args: any) => infer R),則返回any。
- 如果
type ReturnType<T extends (...args: any) => any> = T extends ( ...args: any ) => infer R ? R : any;
參考資料
以上就是TypeScript 工具泛型教程示例的詳細內(nèi)容,更多關于TypeScript 工具泛型的資料請關注腳本之家其它相關文章!
相關文章
TypeError document.getElementById(...) is null錯誤原因
這篇文章主要介紹了TypeError document.getElementById(...) is null錯誤原因,這是很容易犯的一個低級錯誤,需要的朋友可以參考下2015-05-05
解析為什么axios會有params和data兩個參數(shù)
本文給大家分享為什么axios會有params和data兩個參數(shù),先來回顧一下axios的基本使用,怎么發(fā)送一個請求,本文結合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2023-10-10

