溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TypeScript新語法之infer?extends怎么使用

發布時間:2022-08-25 11:29:56 來源:億速云 閱讀:162 作者:iii 欄目:開發技術

TypeScript新語法之infer extends怎么使用

TypeScript 是一種由微軟開發的開源編程語言,它是 JavaScript 的一個超集,添加了可選的靜態類型和基于類的面向對象編程。隨著 TypeScript 的不斷發展,新的語法和特性不斷被引入,以幫助開發者更高效地編寫類型安全的代碼。其中,infer extends 是 TypeScript 4.7 引入的一個新特性,它允許我們在條件類型中更靈活地推斷類型,并且可以對推斷出的類型進行進一步的約束。

本文將詳細介紹 infer extends 的使用方法,并通過多個示例來展示其在實際開發中的應用場景。

1. 什么是 infer extends?

在 TypeScript 中,infer 關鍵字通常用于在條件類型中推斷類型。例如,我們可以使用 infer 來提取函數類型的返回類型:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

在這個例子中,infer R 用于推斷函數類型的返回類型 R。

然而,在某些情況下,我們可能希望對推斷出的類型進行進一步的約束。例如,我們可能希望推斷出的類型必須是某個特定類型的子類型。這就是 infer extends 的用武之地。

infer extends 允許我們在推斷類型的同時,對推斷出的類型進行約束。它的語法如下:

T extends infer U extends Constraint ? U : never;

在這個語法中,U 是推斷出的類型,Constraint 是對 U 的約束條件。如果 U 滿足 Constraint,則返回 U,否則返回 never。

2. infer extends 的基本用法

讓我們通過一個簡單的例子來理解 infer extends 的基本用法。

假設我們有一個類型 MaybeNumber,它可以是 number 類型,也可以是 nullundefined。我們希望定義一個類型 NumberOrNever,如果 MaybeNumbernumber 類型,則返回 number,否則返回 never。

type NumberOrNever<T> = T extends infer U extends number ? U : never;

在這個例子中,U 是推斷出的類型,extends number 是對 U 的約束條件。如果 Unumber 類型,則返回 U,否則返回 never。

讓我們測試一下這個類型:

type A = NumberOrNever<number>; // number
type B = NumberOrNever<string>; // never
type C = NumberOrNever<null>; // never
type D = NumberOrNever<undefined>; // never

正如我們所期望的那樣,NumberOrNever<number> 返回 number,而其他類型返回 never。

3. infer extends 的高級用法

infer extends 不僅可以用于簡單的類型約束,還可以用于更復雜的場景。讓我們通過幾個例子來展示其高級用法。

3.1 提取數組元素的類型并約束

假設我們有一個數組類型 Array<T>,我們希望提取數組元素的類型 T,并且要求 T 必須是 numberstring 類型。

type ArrayElement<T> = T extends Array<infer U extends number | string> ? U : never;

在這個例子中,U 是推斷出的數組元素的類型,extends number | string 是對 U 的約束條件。如果 Unumberstring 類型,則返回 U,否則返回 never。

讓我們測試一下這個類型:

type A = ArrayElement<number[]>; // number
type B = ArrayElement<string[]>; // string
type C = ArrayElement<boolean[]>; // never
type D = ArrayElement<(number | string)[]>; // number | string

3.2 提取函數參數類型并約束

假設我們有一個函數類型 FunctionType,我們希望提取函數的第一個參數的類型,并且要求該參數必須是 string 類型。

type FirstParameter<T> = T extends (arg: infer U extends string, ...args: any[]) => any ? U : never;

在這個例子中,U 是推斷出的函數第一個參數的類型,extends string 是對 U 的約束條件。如果 Ustring 類型,則返回 U,否則返回 never。

讓我們測試一下這個類型:

type A = FirstParameter<(arg: string) => void>; // string
type B = FirstParameter<(arg: number) => void>; // never
type C = FirstParameter<(arg: string, arg2: number) => void>; // string

3.3 提取對象屬性類型并約束

假設我們有一個對象類型 ObjectType,我們希望提取對象中某個屬性的類型,并且要求該屬性必須是 number 類型。

type PropertyType<T, K extends keyof T> = T[K] extends infer U extends number ? U : never;

在這個例子中,U 是推斷出的對象屬性的類型,extends number 是對 U 的約束條件。如果 Unumber 類型,則返回 U,否則返回 never。

讓我們測試一下這個類型:

type A = PropertyType<{ a: number, b: string }, 'a'>; // number
type B = PropertyType<{ a: number, b: string }, 'b'>; // never
type C = PropertyType<{ a: number, b: number }, 'b'>; // number

4. infer extends 的實際應用場景

infer extends 在實際開發中有許多應用場景,特別是在需要精確控制類型推斷的情況下。以下是一些常見的應用場景:

4.1 類型安全的 API 響應處理

在處理 API 響應時,我們通常希望確保響應數據的類型符合預期。例如,我們可能希望確保某個字段是 number 類型。使用 infer extends,我們可以在類型層面進行這種約束。

type ApiResponse<T> = {
  data: T;
  status: number;
};

type SafeNumberResponse<T> = ApiResponse<T> extends { data: infer U extends number } ? U : never;

type ResponseA = SafeNumberResponse<{ data: number }>; // number
type ResponseB = SafeNumberResponse<{ data: string }>; // never

4.2 類型安全的函數參數處理

在編寫高階函數時,我們可能希望確保傳入的函數參數符合特定的類型約束。使用 infer extends,我們可以在類型層面進行這種約束。

type FunctionWithStringArg<T> = T extends (arg: infer U extends string) => any ? U : never;

type FuncA = FunctionWithStringArg<(arg: string) => void>; // string
type FuncB = FunctionWithStringArg<(arg: number) => void>; // never

4.3 類型安全的配置對象處理

在處理配置對象時,我們可能希望確保某些配置項的類型符合預期。使用 infer extends,我們可以在類型層面進行這種約束。

type Config<T> = {
  option: T;
};

type SafeNumberConfig<T> = Config<T> extends { option: infer U extends number } ? U : never;

type ConfigA = SafeNumberConfig<{ option: number }>; // number
type ConfigB = SafeNumberConfig<{ option: string }>; // never

5. 總結

infer extends 是 TypeScript 4.7 引入的一個強大的新特性,它允許我們在條件類型中更靈活地推斷類型,并且可以對推斷出的類型進行進一步的約束。通過 infer extends,我們可以在類型層面實現更精確的類型控制,從而提高代碼的類型安全性和可維護性。

在實際開發中,infer extends 可以應用于多種場景,如 API 響應處理、函數參數處理、配置對象處理等。通過合理地使用 infer extends,我們可以編寫出更加健壯和可靠的 TypeScript 代碼。

希望本文能夠幫助你理解并掌握 infer extends 的使用方法,并在實際項目中靈活運用這一特性。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女