You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何从联合类型中正确移除空接口类型

问题原因

TypeScript 采用结构类型系统进行兼容性判断,空对象类型 {} 可以兼容所有非 null/undefined 的对象类型,因此直接使用 Exclude<Union, A> 时,联合类型里的 B、C、D 都满足 extends {} 的判断条件,会被全部排除,最终得到 never 类型,不符合预期。

解决方案

我们可以自定义工具类型,通过判断类型是否没有自有属性来严格识别空对象,再从联合类型中过滤掉这类空对象:

// 工具类型:判断T是否为严格的空对象类型
type IsStrictEmptyObject<T> = [keyof T] extends [never] ? true : false;

// 工具类型:从联合类型U中移除空对象类型
type RemoveEmptyObject<U> = U extends unknown 
  ? IsStrictEmptyObject<U> extends true 
    ? never 
    : U 
  : never;

// 实际使用
type UnionWithoutA = RemoveEmptyObject<Union>;
// 最终得到的UnionWithoutA类型为:B | C | D

实现原理

  1. keyof T 会返回类型 T 所有自有属性名的联合类型,空对象类型的 keyof 结果为 never,而 B/C/D 都有明确的属性,keyof 结果都是非 never 的字符串字面量联合。
  2. 条件类型中使用 U extends unknown 是为了触发联合类型的分布式条件判断,会遍历联合类型的每一个成员单独执行判断逻辑,符合条件的成员返回 never(即从联合中移除),不符合的成员保留,最终合并得到过滤后的联合类型。

内容的提问来源于stack exchange,提问作者Albert Gao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:00:01