Exclude 工具類型八個(gè)使用技巧
Exclude 是 TypeScript 中內(nèi)置的工具類型,它用于從一個(gè)聯(lián)合類型中排除掉你不希望包含的類型,生成一個(gè)新的類型。這個(gè)工具類型在日常開(kāi)發(fā)中非常有用,它能夠幫助我們編寫(xiě)類型安全的代碼和更好地實(shí)現(xiàn)代碼復(fù)用。
/**
* Exclude from T those types that are assignable to U.
* typescript/lib/lib.es5.d.ts
*/
type Exclude<T, U> = T extends U ? never : T;
type T0 = Exclude<"a" | "b" | "c", "a" | "b">
// type T0 = "c"
本文我將介紹 Exclude 工具類型的 8 個(gè)使用技巧,掌握這些技巧之后,在工作中你就能更好地利用 Exclude 工具類型來(lái)滿足不同的使用場(chǎng)景。
1.排除指定的基本數(shù)據(jù)類型
type MyTypes = string | number | boolean;
type StringOrNumber = Exclude<MyTypes, boolean>;
let uid: StringOrNumber = "semlinker" // Ok
uid = 2024 // Ok
uid = false // Error
// Type 'boolean' is not assignable to type 'StringOrNumber'.
2.排除 string 或 number 類型的子類型
type Status = "success" | "error" | 200 | 500;
type StringStatus = Exclude<Status, number>;
// type StringStatus = "success" | "error"
type NumberStatus = Exclude<Status, string>
// type NumberStatus = 200 | 500
3.排除兩個(gè)聯(lián)合類型的共有成員
type TaskStatus = "Todo" | "InProgress" | "Done" | "Archived";
type ModuleHandledStatus = "Todo" | "Done" | "OnHold";
type TaskOnlyStatus = Exclude<TaskStatus, ModuleHandledStatus>;
// type TaskOnlyStatus = "InProgress" | "Archived"
4.排除含有特定屬性的子類型
Animal 聯(lián)合類型,包含了多種動(dòng)物的描述對(duì)象,我們想從中排除含有 "legs" 屬性的子類型。
type Animal =
| { type: 'dog', legs: number }
| { type: 'cat', legs: number }
| { type: 'fish', fins: number };
type AnimalsWithFins = Exclude<Animal, { legs: number }>;
const fish: AnimalsWithFins = { type: 'fish', fins: 6 }; // Ok
const dog: AnimalsWithFins = { type: 'dog', legs: 4 }; // Error
// Type '"dog"' is not assignable to type '"fish"'.
5.排除同個(gè)屬性不同類型的子類型
除了可以使用 Exclude<Animal, { legs: number }> 來(lái)創(chuàng)建 AnimalsWithFins 類型,該類型還可以通過(guò) Exclude<Animal, { type: 'dog' | 'cat' }> 這種方式來(lái)創(chuàng)建。
type Animal =
| { type: 'dog', legs: number }
| { type: 'cat', legs: number }
| { type: 'fish', fins: number };
type AnimalsWithFins = Exclude<Animal, { type: 'dog' | 'cat' }>;
const fish: AnimalsWithFins = { type: 'fish', fins: 6 }; // Ok
const dog: AnimalsWithFins = { type: 'dog', legs: 4 }; // Error
// Type '"dog"' is not assignable to type '"fish"'.
6.排除枚舉類型的某些成員
利用 Exclude 工具類型可以排除枚舉中的某些成員,從而得到一個(gè)新的類型。
enum Status { New, InProgress, Done, Cancelled }
type ActiveStatus = Exclude<Status, Status.Done | Status.Cancelled>;
// type ActiveStatus = Status.New | Status.InProgress
7.排除指定前綴的字符串字面量類型
利用 Exclude 工具類型和模板字面量類型,我們可以實(shí)現(xiàn)從字符串字面量聯(lián)合類型中,排除指定前綴或后綴的字符串字面量。
type LogEvent =
| "userLogin"
| "userLogout"
| "systemException"
| "systemCrash"
| "performanceLoadTime"
| "performanceApiResponse";
type SystemAndPerformanceEvents = Exclude<LogEvent, `user${string}`>;
// type SystemAndPerformanceEvents = "systemException" | "systemCrash" | "performanceLoadTime" | "performanceApiResponse"
8.排除不同格式的字符串字面量類型
type LogEvent =
| "userLogin"
| "userLogout"
| "UserLogin" // New
| "UserLogout" // New
| "systemException"
| "systemCrash"
| "performanceLoadTime"
| "performanceApiResponse";
type SystemAndPerformanceEvents = Exclude<LogEvent, `${"user" | "User"}${string}`>;
// type SystemAndPerformanceEvents = "systemException" | "systemCrash" | "performanceLoadTime" | "performanceApiResponse"