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

如何通过标签键与对应值创建Tagged Union(标记联合)实例

实现约束标记联合类型的泛型构造函数

要实现一个能正确关联标记联合类型的标签与对应值的泛型函数,你需要确保标签和值的类型是一一绑定的——原有的实现中,UnionKey<T>和UnionValue<T>会提取联合类型所有可能的标签和值的集合,导致标签和值之间没有关联,无法阻止错误的组合。

正确实现方案

type TagA = 'x' | 'y' | 'z';
type TagB = 'm' | 'n';

type UnionExampleA = 
    | { tag: 'x', value: number}
    | { tag: 'y', value: [number, number]}
    | { tag: 'z', value: string}

type UnionExampleB = 
    | { tag: 'm', value: string}
    | { tag: 'n', value: null}

// 提取联合类型T的所有标签值
type UnionTag<T> = T extends { tag: infer R } ? R : never;

// 从联合类型T中筛选出标签为K的成员类型
type UnionMemberByTag<T, K extends UnionTag<T>> = 
    T extends { tag: K } ? T : never;

// 获取指定标签K对应的value类型
type UnionValueByTag<T, K extends UnionTag<T>> = 
    UnionMemberByTag<T, K>['value'];

function createUnionInstance<T, K extends UnionTag<T>>(
    tag: K,
    value: UnionValueByTag<T, K>
): UnionMemberByTag<T, K> {
    return { tag, value } as UnionMemberByTag<T, K>;
}

使用示例

// 正确调用:自动推导标签对应的value类型
const a = createUnionInstance<UnionExampleA>('y', [15, 25]);
// 显式指定标签类型(可选)
const aExplicit = createUnionInstance<UnionExampleA, 'y'>('y', [15, 25]);

const b = createUnionInstance<UnionExampleB>('m', '25');

// 以下错误调用均无法通过编译:
// 标签不属于目标联合类型的标签集合
// const c = createUnionInstance<UnionExampleB>('y', [15, 25]);
// 值的类型与标签不匹配
// const d = createUnionInstance<UnionExampleB>('m', [15, 25]);

实现说明

  • UnionTag<T>:通过条件类型的分布式特性,提取联合类型所有成员的tag字段值,得到标签的联合类型。
  • UnionMemberByTag<T, K>:遍历联合类型的每个成员,筛选出tag等于指定值K的成员,确保返回的是该标签对应的具体类型。
  • UnionValueByTag<T, K>:基于筛选出的成员类型,提取对应的value类型,保证标签和值的类型严格绑定。
  • 泛型函数createUnionInstance通过两个泛型参数约束标签和值的对应关系,错误的标签值组合会在编译阶段直接被拦截,完全符合预期需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:20:28