TypeScript 工具泛型教程示例
前言
Typescript 中默認(rèn)內(nèi)置了很多工具泛型,通過使用這些工具,可以使得我們定義類型更加靈活,高效。本文將會介紹常用泛型工具的使用技巧,以及對其實(shí)現(xiàn)原理進(jìn)行相應(yīng)的解析,如果有錯(cuò)誤的地方,還望指出。
Partial\<T>
作用:將傳入對象類型 T 的屬性變?yōu)?strong>可選屬性。
示例:
interface Person {
name: string;
age: number;
}
const tom: Partial<Person> = {
name: "Tom",
};javascript:void(0)Partial<Person> 等價(jià)于
interface Person {
name?: string;
age?: number;
}實(shí)現(xiàn)原理:
- 通過關(guān)鍵字
keyof將傳入對象類型的鍵值轉(zhuǎn)換為聯(lián)合類型。 - 通過關(guān)鍵字
in遍歷聯(lián)合類型,即遍歷對象的鍵值。 - 通過類型映射,將對象的屬性轉(zhuǎ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> 等價(jià)于
interface Person {
readonly name: string;
readonly age: number;
}實(shí)現(xiàn)原理:
與Partial類似:
- 通過關(guān)鍵字
keyof將傳入對象類型的鍵值轉(zhuǎn)換為聯(lián)合類型。 - 通過關(guān)鍵字
in遍歷聯(lián)合類型,即遍歷對象的鍵值。 - 通過類型映射,將對象的屬性轉(zhuǎ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實(shí)現(xiàn)原理:
與Partial類似:
- 通過關(guān)鍵字
keyof將傳入對象的鍵值轉(zhuǎn)換為枚舉類型。 - 通過關(guān)鍵字
in遍歷枚舉類型,即遍歷對象的鍵值。 - 通過類型映射,再統(tǒng)一通過
-?修飾符移除?修飾符,從而轉(zhuǎn)變?yōu)?strong>必填狀態(tài)。
type Required<T> = {
Required [P in keyof T]: T[P];
};Record\<K,T>
作用:它用來生成一個(gè)屬性名為 K,屬性值類型為 T 的對象類型集合。
示例:
// 快速生成一個(gè) Person 對象
type Person = Record<"name" | "country", string>;
const Tom: Person = { name: "Tom", country: "America" };實(shí)現(xiàn)原理:
- 通過
K extends keyof any對K參數(shù)進(jìn)行約束,將其約束為任意類型any的鍵值。 - 通過
in對鍵值集合K進(jìn)行遍歷,然后生成類型為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
實(shí)現(xiàn)原理:
通過條件類型
T extends U ? never : T對T參數(shù)進(jìn)行判別:- 如果
T可賦值給U,那么返回never(即排除掉T)。 - 如果
T不可賦值給U,那么返回T。
- 如果
- 通過分布式條件類型,如果
T為聯(lián)合類型,則將條件類型的結(jié)果分發(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>; // 相當(dāng)于 type T3 = () => void;
實(shí)現(xiàn)原理:
與 Exclude 類似:
通過條件類型
T extends U ? never : T對T參數(shù)進(jìn)行判別:- 如果
T可賦值給U,那么返回T。 - 如果
T不可賦值給U,那么返回never(即排除掉T)。
- 如果
- 通過分布式條件類型,如果
T為聯(lián)合類型,則將條件類型的結(jié)果分發(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",
};實(shí)現(xiàn)原理:
- 通過
K extends keyof T對K參數(shù)進(jìn)行約束,將其約束為T的鍵值范圍內(nèi)。 - 通過
in對鍵值集合K進(jìn)行遍歷,然后生成類型為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,
};實(shí)現(xiàn)原理:
- 通過
K extends keyof T對K參數(shù)進(jìn)行約束,將其約束為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 }實(shí)現(xiàn)原理:
- 通過
extends對T參數(shù)進(jìn)行約束,(...args: any) => any表示一個(gè)函數(shù)類型,即T參數(shù)的類型必須是一個(gè)函數(shù)類型。 T extends U ? X : Y是條件類型(注意和之前表示約束的extends做區(qū)分),其中T是泛型參數(shù),U是條件部分,X是符合條件的返回結(jié)果,Y是不符合條件的返回結(jié)果。- 推斷類型
infer的作用是:在條件類型內(nèi)部聲明一個(gè)類型變量。(...args: any) => infer R是條件類型的條件部分,它聲明了一個(gè)類型變量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 工具泛型教程示例的詳細(xì)內(nèi)容,更多關(guān)于TypeScript 工具泛型的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
七行JSON代碼把你的網(wǎng)站變成移動應(yīng)用過程詳解
這篇文章主要介紹了七行JSON代碼把你的網(wǎng)站變成移動應(yīng)用過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值2019-07-07
TypeError document.getElementById(...) is null錯(cuò)誤原因
這篇文章主要介紹了TypeError document.getElementById(...) is null錯(cuò)誤原因,這是很容易犯的一個(gè)低級錯(cuò)誤,需要的朋友可以參考下2015-05-05
微信小程序進(jìn)入廣告實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了微信小程序進(jìn)入廣告實(shí)現(xiàn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
Tabella.js項(xiàng)目常見問題及解決方案詳解
Tabella.js是純JavaScript響應(yīng)式表格插件,支持觸摸操作與AMD模塊加載,這篇文章主要介紹了Tabella.js項(xiàng)目常見問題及解決方案的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-05-05
javascript正則表達(dá)式模糊匹配IP地址功能示例
這篇文章主要介紹了javascript正則表達(dá)式模糊匹配IP地址功能,結(jié)合簡單實(shí)例形式演示了JS模糊匹配IP地址的實(shí)現(xiàn)方法,涉及針對數(shù)字及字符串的相關(guān)正則判定與匹配操作技巧,需要的朋友可以參考下2017-01-01
解析為什么axios會有params和data兩個(gè)參數(shù)
本文給大家分享為什么axios會有params和data兩個(gè)參數(shù),先來回顧一下axios的基本使用,怎么發(fā)送一個(gè)請求,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2023-10-10

