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

如何从含嵌套联合类型的TypeScript接口中提取精确子类型?

解决嵌套联合类型的提取问题

这个问题我之前在项目里也碰到过,核心卡点在于**Extract只对顶层联合类型生效**——你的X是一个单一接口,里面的prop是嵌套的联合类型,所以直接用Extract去匹配时,根本找不到符合条件的顶层分支,自然返回never。

改成顶层联合(type X = { prop: Y } | { prop: Z })确实能解决,但手动改整个代码库显然不现实。我们可以写一个通用的类型工具,自动把所有嵌套的联合类型展开成顶层的笛卡尔积联合,这样就能继续用Extract来筛选了。

通用类型工具实现

下面是两个核心类型工具,能递归展开所有嵌套的联合类型:

// 拆分单个属性的联合,生成对应分支
type DistributeSingleProp<T, K extends keyof T> = 
  T[K] extends infer U
    ? U extends any
      ? Omit<T, K> & { [P in K]: U }
      : never
    : never;

// 递归遍历所有属性,展开所有嵌套联合
type ExpandAllNestedUnions<T> = 
  T extends object
    ? keyof T extends infer K
      ? K extends keyof T
        ? ExpandAllNestedUnions<DistributeSingleProp<T, K>>
        : T
      : T
    : T;

使用示例

用你的类型定义来测试:

interface Y { readonly y: string; readonly type: 'y' }
interface Z { readonly z: number; readonly type: 'z' }
interface X { readonly prop: Y | Z }

// 先展开嵌套联合:此时 ExpandedX 等价于 { readonly prop: Y } | { readonly prop: Z }
type ExpandedX = ExpandAllNestedUnions<X>;

// 再用 Extract 筛选,就能得到预期的类型
type ZfromX = Extract<ExpandedX, {readonly prop: { readonly type: 'z' }}>;
// ZfromX 的结果是 { readonly prop: Z }

工具的通用性

这个工具不止能处理单个属性的嵌套联合,哪怕你的类型有多个带联合的属性,比如:

interface A { a: 'a1' | 'a2' }
interface B { b: 'b1' | 'b2' }
type C = { prop1: A; prop2: B };

type ExpandedC = ExpandAllNestedUnions<C>;
// ExpandedC 会展开成四个分支的联合:
// { prop1: { a: 'a1' }, prop2: { b: 'b1' } } | 
// { prop1: { a: 'a1' }, prop2: { b: 'b2' } } | 
// { prop1: { a: 'a2' }, prop2: { b: 'b1' } } | 
// { prop1: { a: 'a2' }, prop2: { b: 'b2' } }

这样不管你的类型结构多复杂,都能自动把所有嵌套的联合展开成顶层的笛卡尔积联合,之后用Extract、Exclude这些工具就都能正常工作了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:37:32