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

如何将TypeScript可辨识联合类型动态映射为另一可辨识联合类型

TypeScript可辨识联合类型的动态映射方案

先看我们的原始可辨识联合类型定义:

type Shape = Triangle | Rectangle;

interface Triangle {
    type: "triangle";
    base: number;
    height: number;
}

interface Rectangle {
    type: "rectangle";
    width: number;
    height: number;
}

要把它动态转换成如下的ShapeMessage联合类型:

type ShapeMessage =
  | {
      contentType: "application/vnd.shape.triangle";
      content: {
        base: number;
        height: number;
      };
    }
  | {
      contentType: "application/vnd.shape.rectangle";
      content: {
        width: number;
        height: number;
      };
    };

可以通过TypeScript的泛型映射类型+条件类型实现完全动态的转换,不需要手动逐个定义:

// 定义通用的转换泛型
type ShapeToMessage<S extends { type: string }> = {
  // 遍历联合类型中所有的type字面量值
  [K in S['type']]: {
    // 用模板字面量生成指定格式的contentType
    contentType: `application/vnd.shape.${K}`;
    // 提取对应type的子类型,再去掉type属性作为content
    content: Omit<Extract<S, { type: K }>, 'type'>;
  };
// 最后将映射后的对象类型转为联合类型
}[S['type']];

// 生成目标类型
type ShapeMessage = ShapeToMessage<Shape>;

代码解释:

  • S extends { type: string } 约束泛型参数必须是带有type辨识属性的类型
  • S['type'] 提取出联合类型中所有type的字面量值(这里就是"triangle" | "rectangle")
  • 映射类型[K in S['type']] 为每个type值生成对应的消息结构
  • Extract<S, { type: K }> 从联合类型中筛选出type等于K的子类型
  • Omit<..., 'type'> 移除子类型中的type属性,只保留业务字段作为content
  • 最后通过[S['type']]索引访问,把映射后的对象类型拆解成联合类型,和手动定义的ShapeMessage完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:22:34