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

如何在TypeScript中区分包含多判别值成员的联合类型?

解决含多判别值的联合类型筛选问题

你定义的联合类型包含了带有多个判别值的Simple接口和独立的Complex接口,但现有DiscriminateUnion工具类型无法正确筛选出带有'bar'判别值的Simple类型,返回了never。原代码如下:

interface Simple {
    type: 'foo' | 'bar';
    field: string;
}

interface Complex {
    type: 'quux';
    whoa: string;
    so: string;
    many: string;
    fields: string;
}

type All = Simple | Complex;

type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = T extends Record<K, V> ? T : never;

// 符合预期:Complex
type t1 = DiscriminateUnion<All, 'type', 'quux'>;

// 结果为never :( 
type t2 = DiscriminateUnion<All, 'type', 'bar'>;

问题根源

原工具类型使用Record<K, V>做判断,要求目标类型的K字段完全等于V。但Simple的type是'foo' | 'bar',并不等于单一值'bar',所以被判定为不符合条件,返回never。

修改后的工具类型

我们需要调整逻辑,判断传入的V是否是目标类型K字段的子集,而非要求完全相等。修改后的类型工具如下:

type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = 
  T extends { [P in K]: infer U } 
    ? V extends U 
      ? T 
      : never 
    : never;

验证效果

用修改后的类型测试:

// 结果为Simple,符合预期
type t2 = DiscriminateUnion<All, 'type', 'bar'>;
// 结果同样为Simple
type t3 = DiscriminateUnion<All, 'type', 'foo'>;
// 结果为Complex,符合预期
type t1 = DiscriminateUnion<All, 'type', 'quux'>;

逻辑说明

  1. 通过T extends { [P in K]: infer U }提取联合类型中每个成员的K字段类型,保存到U
  2. 判断传入的筛选值V是否是U的子集(V extends U)
  3. 满足条件则保留该类型成员,否则返回never

这样既不用拆分Simple接口,也能正确筛选出包含目标判别值的类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:37:26