TypeScript类型编程中的extends和infer示例解析
本文详细解析TypeScript类型编程中extends和infer的核心用法。通过条件判断、参数约束及局部变量声明等示例,展示如何利用extends限制类型范围,以及利用infer提取复杂类型中的子类型。文章还涵盖了ReturnType和Parameters等内置工具类型的实现原理,帮助开发者掌握高级类型定义技巧。
引文
在初学TypeScript时,type和interface是最常用的类型声明关键字,通常足以应对日常开发需求。然而,当需要构建更复杂的高级类型系统时,仅依靠基础语法往往力不从心。
构建高级类型涉及类型编程的概念,其中两个关键机制至关重要:extends和infer。
extends主要用于约束输入参数的类型以及执行条件判断,而infer则用于声明局部类型变量以进行类型推导。
extends
条件判断
通过一个简单示例来说明其工作原理。
type isOne<T extends number> = T extends 1 ? true : false单独观察T extends 1 ? true : false部分,其语法结构与JavaScript中的三元表达式类似,但部分开发者可能不清楚这里的extends具体指代什么含义。
表达式T extends 1 ? true : false的含义是:检查传入的类型T是否可以赋值给字面量类型1。如果可以,则返回true;否则返回false。
约束参数类型
沿用上述示例,单独分析T extends number,此处的extends表示限制传入的类型T必须为number类型,否则将引发类型错误。
为何需要这种限制?
因为我们的目标是判断类型T是否能赋值给字面量类型1。如果传入的参数根本就不是number类型,那么后续的赋值判断就失去了意义,因此需要预先约束参数类型。
约束infer推导的局部变量类型
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest]
? `${FirstChar}`
: never;
type Res = GetFirst<['1', '2', '3']>;查看报错信息可知,虽然传入的参数类型被限制为string类型的数组,但infer推导出的局部变量类型实际上是unknown类型,从而导致类型不匹配。

解决该问题有三种方法:
对FirstChar使用extends进行预先过滤。
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest]
? FirstChar extends string
? `${FirstChar}`
: never
: never;将FirstChar与string类型进行交叉运算。
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest]
? `${FirstChar & string}`
: never;使用infer extends语法进行类型转换。
type GetFirst<T extends string[]> = T extends [
infer FirstChar extends string,
...infer Rest
]
? `${FirstChar}`
: never;infer extends特性在TypeScript 4.7版本中引入,低于该版本的编译器不支持此用法。
类型转换
type StrToNum<T extends string> = T extends `${infer Num extends number}` ? Num : T
type Res = StrToNum<"1">
// ts 4.7时,返回的结果是type Res = number
// ts 4.8及以上, 返回的结果是type Res = 1infer
继续通过示例进行讲解,以下示例旨在提取被Promise包裹的内部类型。
type PromiseValue<T extends Promise<unknown>> = T extends Promise<infer Value> ? Value : never
type Res = PromiseValue<Promise<string>> // string绘制一张简图来描述变量类型的提取过程。

注意:infer声明的局部变量仅在条件语句为true的分支中可用。

如果在false分支中尝试使用由infer声明的局部变量,编译器会直接报错,提示找不到该变量。
组合使用
ReturnType
内置工具类型RetureType用于获取函数的返回值类型。
type MyReturnType<T extends (...args: any) => any>
= T extends (...args: any) => infer R
? R
: any;
type Res = MyReturnType<() => string> // type Res = stringParameters
内置工具类型Parameters用于获取函数的参数类型。
type MyParameters<T extends (...args: any) => any>
= T extends (...args: infer P) => any
? P
: never;
type Res = MyParameters<(a: string, b: number) => void> // type Res = [a: string, b: number]以上便是TypeScript类型编程中关于extends和infer的示例解析,更多TypeScript类型编程中extends和infer的相关资料请继续关注本站其他文章!
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53








