extends 条件类型怎么定义?
下文默认基于 TypeScript 5.x,并假设开启
strict: true。
面试速答(30 秒版 TL;DR)
- 条件类型的基本语法是:
T extends U ? X : Y
- 含义是:如果
T可以赋值给U,结果就是X,否则就是Y。 - 它常用来做:
- 类型分支判断;
- 联合类型过滤;
- 提取函数参数、返回值;
- 配合
infer做类型推导。
- 面试里要补一句:
- 这里的
extends不是“继承实现”,而是“类型约束/可赋值关系判断”。
- 这里的
心智模型:在类型系统里写 if...else
1. 最基础的定义方式
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
标准解释:
IsString<T>是一个条件类型;- 当
T满足extends string时返回true; - 否则返回
false。
2. 为什么它叫“条件类型”
因为它跟运行时的三元表达式很像:
condition ? a : b;
只是这里判断的不是值,而是类型关系。
所以可以把它理解成:
- 运行时里你写
if; - 类型系统里你写
extends ? :。
3. 常见用法一:按条件返回不同结构
type WrapIfString<T> = T extends string ? { value: T } : T;
type A = WrapIfString<string>; // { value: string }
type B = WrapIfString<number>; // number
这说明条件类型的意义不是“炫技”,而是让类型能跟输入条件联动变化。
4. 常见用法二:过滤联合类型
type KeepString<T> = T extends string ? T : never;
type Result = KeepString<string | number | boolean>; // string
为什么能过滤?
因为联合类型会被逐个分支判断,最后把结果合并回来。
这也是 Exclude、Extract 这类工具类型的核心原理。
5. 常见用法三:配合 infer 提取类型
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type R = GetReturnType<() => Promise<string>>; // Promise<string>
这里的 infer R 可以理解成:
- 如果匹配到了某种函数结构;
- 那就把它的返回值类型“推导出来”并命名为
R。
这是高级类型题里非常高频的组合。
6. extends 在这里不是“继承”
这点经常混。
比如:
type X<T> = T extends string ? 1 : 2;
这里的 extends 更接近:
T是否可以赋值给string;T是否满足某个约束条件。
它不是 class 之间那种运行时继承关系。
7. 怎么阻止联合类型分发
type ToArray<T> = T extends any ? T[] : never;
type A = ToArray<string | number>; // string[] | number[]
如果你想把联合当成整体判断,可以包一层:
type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;
type B = ToArrayNonDist<string | number>; // (string | number)[]
这一点是条件类型里的经典追问。
8. 高频面试题标准答法
8.1 extends 条件类型最常见的形式是什么
直接答:
type Xxx<T> = T extends U ? X : Y;
8.2 它和泛型约束里的 T extends U 是一回事吗
有关联,但语义位置不同:
function foo<T extends U>() {}是泛型参数约束;type R<T> = T extends U ? X : Y是条件分支判断。
8.3 为什么很多工具类型都基于条件类型
因为它能做三件事:
- 判断;
- 过滤;
- 提取。
这正是高级类型运算最需要的能力。
9. 常见误区
- 误区 1:把这里的
extends理解成类继承。- 条件类型里它更像“是否满足条件”。
- 误区 2:看到联合类型分发就懵。
- 记住“裸类型参数会逐个成员判断”。
- 误区 3:只会背语法,不知道它能做什么。
- 真正价值是构建可复用的类型工具。
速记要点
- 条件类型语法:
T extends U ? X : Y。 - 本质是在类型系统里写条件判断。
- 常配合联合类型过滤和
infer提取一起使用。