Exclude<T, U> Exclude(含 Extract)
最后更新:2026-10-22
Exclude<T, U> Exclude(含 Extract)
Exclude<T, U> 从联合类型 T 中剔除"可赋给 U"的成员,常用来从大联合里裁掉不关心的分支。它的反向操作 Extract<T, U> 只保留可赋给 U 的成员。两者都基于条件类型的分配特性。
| 分组 | 工具类型 |
|---|---|
| 类型 | 类型 |
| 严格模式 | 不需要 |
ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。
📝 语法
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
// 用法
type PassiveEvent = Exclude<EventType, "click" | "keydown">;
type Interactive = Extract<EventType, "click" | "keydown">;
⚙️ 参数
| T | 源联合类型,逐个成员参与条件判断(分配律) |
|---|---|
| U | 筛选条件:可赋给 U 的成员被剔除(Exclude)或保留(Extract) |
返回值:一个新联合类型:Exclude 是 T 减去 U 的差集;Extract 是 T 与 U 的交集。
▶ 示例
修改下面的代码,点击试一试查看转译运行结果:
输出:
focus | scroll | wheel
click | keydown
(转译后运行输出;类型层面的效果:往 passiveEvents 里 push "click" 会编译报错——它已被 Exclude 从 PassiveEvent 中剔除)
💡 要点
ℹ️ 说明 原理是"分配条件类型":T 是联合时,T extends U 会逐个成员判断再合并结果。所以成员命中 U 就变成 never(从联合中消失),这就是"剔除"的实现。
⚠️ 注意 这两个工具只对联合类型有意义。对对象类型直接用(T 不是联合)时不会逐属性处理,行为容易与直觉不符——操作对象属性请用 Omit/Pick。
💡 提示 NonNullable<T> 就是 Exclude<T, null | undefined> 的专用别名。记住这一层关系,Exclude 的理解可以直接迁移过去。
🏷️ 相关工具类型
💡 相关案例
更多案例即将上线。
📚 相关教程
❓ 常见问题
Q Exclude 和 Omit 有什么区别?
A Exclude 操作联合类型的"成员",Omit 操作对象类型的"属性键"。Omit 内部正是用 Exclude 实现:Exclude<keyof T, K> 先剔除键,再 Pick。一个管成员,一个管键。
Q 为什么叫"分配"?不分配会怎样?
A 不分配时 T extends U 会把 "click"|"focus"|... 当成一个整体与 U 比较,整体不可赋给 U,结果什么都不剔。分配让每个成员单独判断——这正是逐个"筛选"联合成员的机制。
Q Exclude 能剔除对象成员吗?
A 可以,只要成员类型可赋给 U。例如 type Shape = Circle | Square; type RoundOnly = Exclude<Shape, Square>; 会剔除 Square。判断标准始终是"可赋值",不只是字面量相等。