返回
在 TypeScript 中巧妙运用 Infer Extends:全面解析与实用案例
前端
2023-10-09 05:51:02
简介
TypeScript 作为一门强大的类型化编程语言,提供了丰富的类型系统,其中 infer extends 机制是一个非常有用的功能,它允许我们从类型中提取部分类型,并将其存储为一个新的类型变量。这种模式匹配的方式在各种场景下都有着广泛的应用,例如从元组中提取最后一个元素的类型、推断函数的返回值类型,甚至是字符串处理。
理解 Infer Extends
infer extends 的语法格式如下:
type NewType = infer T extends SomeType
其中 NewType 是新的类型变量,它将存储从 SomeType 中提取的一部分类型。 extends 指定了模式匹配的规则,我们可以在其中指定具体的类型模式。
例如,以下代码从一个元组类型中提取最后一个元素的类型:
type LastElement<T extends [any, ...any[]]> = infer U extends T[number]
在这个例子中,模式匹配规则指定了 T 必须是一个元组,并且其最后一个元素的类型存储在 U 中。
实用案例
元组类型
- 提取最后一个元素的类型:
type LastElement<T extends [any, ...any[]]> = infer U extends T[number]
- 提取前面 N 个元素的类型:
type FirstNElements<T extends [any, ...any[]], N extends number> = infer U extends T[number][]
函数类型
- 推断函数的返回值类型:
type ReturnType<T extends (...args: any[]) => any> = infer R extends T extends (...args: any[]) => infer R ? R : any
- 检查函数是否返回 Promise:
type IsPromise<T extends (...args: any[]) => any> = infer R extends T extends (...args: any[]) => Promise<infer R> ? true : false
字符串处理
- 提取字符串的一部分:
type Substring<T extends string, Start extends number, End extends number> = infer S extends T extends `${string.substring(0, Start)}${infer S}${string.substring(End)}` ? S : never
- 替换字符串的一部分:
type ReplaceSubstring<T extends string, From extends string, To extends string> = infer S extends T extends `${string.substring(0, From.length)}${infer S}${string.substring(From.length + To.length)}` ? `${string.substring(0, From.length)}${To}${S}` : never
其他用法
- 类型条件约束:
type IsArray<T> = infer U extends T[] ? true : false
- 条件类型:
type Condition<T extends true, TrueType, FalseType> = infer U extends T ? TrueType : FalseType
总结
TypeScript 的 infer extends 机制为我们提供了强大的类型推断能力,它使我们能够从各种类型中提取部分类型,从而实现更灵活和动态的类型化编程。通过上述实用案例,我们展示了 infer extends 在元组类型、函数类型、字符串处理以及其他场景中的应用,帮助开发者充分利用 TypeScript 的类型系统,编写出更高效、更可维护的代码。