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

TypeScript递归映射可选可空类型 实现自定义类型转换

TypeScript 类型转换优化方案

核心优化点

  • 简化可空/可选修饰保留逻辑:利用分布式条件类型自动处理联合类型的null/undefined透传,删除冗余的多分支判断
  • 支持批量传入转换规则:无需嵌套调用,直接传入转换规则数组即可批量处理多组类型替换

完整实现代码

// 原有基础类型定义
type DateJson = {
  __type: 'Date';
  iso: string;
}
interface Pointer {
  __type: 'Pointer';
  className: string;
  objectId: string;
}
interface ParseObject {
  __type: 'Object';
  className: string;
}

// 转换规则类型定义
type ReplaceRule = [source: unknown, target: unknown]

// 单组转换规则的递归替换
type DeepReplaceSingle<T, S, R> = {
  [K in keyof T]: T[K] extends null | undefined
    ? T[K]
    : T[K] extends S
      ? R
      : T[K] extends Record<string, unknown>
        ? DeepReplaceSingle<T[K], S, R>
        : T[K]
}

// 多组转换规则的批量递归替换
type DeepReplace<T, Rules extends ReplaceRule[]> = 
  Rules extends [infer FirstRule extends ReplaceRule, ...infer RestRules extends ReplaceRule[]]
    ? DeepReplace<DeepReplaceSingle<T, FirstRule[0], FirstRule[1]>, RestRules>
    : T

// 最终使用的转换类型,新增转换规则直接在数组中添加即可
type ParseAttributes<T> = DeepReplace<T, [
  [Pointer, ParseObject],
  [DateJson, Date]
]>

效果验证

用你提供的测试类型验证:

type Test = {
  user: Pointer;
  employee?: {
    pointer?: Pointer | null;
    name: string;
    company: string;
  };
  date?: DateJson;
  other: {
    date: DateJson | null;
    testKey: number;
  };
  nested: {
    date: DateJson;
    deep: {
     pointer: Pointer | null
     another: {
       test?: string;
       date?: DateJson | null
     }
   }
  }
}

// 转换后的结果和你期望的输出完全一致
type ConvertedTest = ParseAttributes<Test>

扩展说明

后续新增需要转换的类型时,只需在ParseAttributes的规则数组中新增对应[源类型, 目标类型]项即可,无需修改核心递归逻辑。默认递归深度足够覆盖常规业务场景的嵌套层级需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:48:04