如何理解 TS 类型编程中的 extends 和 infer
2021/12/29 17:07:25
本文主要是介绍如何理解 TS 类型编程中的 extends 和 infer,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
extends
extends 在TS类型编程中用法(T extends U),表示 T 中的某些在 U 里面,比较难描述,用法如下:
T extends U ? X : Y
分为两种情况理解更直观一些:
1)如果 T 不是一个联合类型,表示如果 T 是 U 的子集,那么返回 X 否则返回 Y。
举个例子,在下面的例子中,如果 T 是 U 的子集,那么返回 number,否则返回 never。
export type TExtends<T, U> = T extends U ? number : never; // T(number)是 U(number | string)的子集,所以返回number type TExtendsExample1 = TExtends<number, number | string>; // number // T(boolean) 不是 U(number | string)的子集,所以返回never type TExtendsExample2 = TExtends<boolean, number | string>; // never
2)如果 T 是一个联合类型,表示如果 T 中的类型是 U 的子集,那么返回 X 否则返回 Y。这个过程可以理解为对T中的类型进行一次遍历,每个类型都执行一次 extends。
举个例子:
下面的例子中对 T 中的每个类型进行遍历,检测是否是 extends 于 null 或 undefined。如果满足这个条件就返回 never(对于联合类型来说如果返回never那就相当于不存在,因为never是所有类型的子类型),如果不满足就返回原来的类型。
type NonNullable<T> = T extends null | undefined ? never : T; // T(number | string) 不是 U(null | undefined) 的子集,所以返回 T type TNonNullableExample1 = NonNullable<number | string>; // number | string // T(string | null) 中 string 不是 U 的子集返回 string,null 是 U 的子集,返回 never type TNonNullableExample2 = NonNullable<string | null>; // string
infer
infer 可以推断一个类型变量,常见用法示例:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
infer R 相当于声明一个类型变量,这个变量的类型取决于传入的泛型 T,在之前的时候 extends 右边的类型是写死的,但是在这里通过 infer R 来代替写死的类型,并且具体的类型取决于传入的泛型。
不过需要注意,R 变量只能在 true 的分支可以使用,也就是只能在 ? 的第一个分支中使用。
下面通过两个例子进行说明:
1)如果 T 是 () => infer R 的子集,那么返回 R,否则返回 number
{ type Func<T> = T extends () => infer R ? R : number; // T(string) 不是 () => infer R 的子集,因此返回 number type TFuncExample1 = Func<string>; // number // T(() => boolean) 是 () => infer R 的子集,并且通过传入的() => boolean可以推断出 R 是 boolean,因此返回 R(boolean) type TFuncExample2 = Func<() => boolean>; // boolean }
2)如果 T 是 {a: infer VType, b: infer VType}
的子集,那么返回 UType | VType
,否则返回number。
type TObj<T> = T extends { a: infer VType, b: infer UType} ? VType | UType : number; // T(string)不是 {a: infer VType, b: infer UType} 的子集,因此返回 number type TObjExample1 = TObj<string>; // number // T(string)是 {a: infer VType, b: infer UType} 的子集,因此返回 UType | VType type TObjExample2 = TObj<{ a: number, b: string }>; // => number | string
完。
这篇关于如何理解 TS 类型编程中的 extends 和 infer的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南