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

TypeScript递归条件类型:如何递归映射对象转换原始值类型?

递归转换对象原始值为指定类型的TypeScript方案

这是个很常见的递归类型转换需求,我们可以通过分层判断类型分支,结合TypeScript的条件类型和递归语法来实现完全嵌套的转换。下面是针对你需求的完整解决方案:

实现思路

我们需要分三个核心分支处理不同类型:

  • 对于JSON可序列化的原始值(string/number/boolean):直接替换为目标Test类型
  • 对于数组:递归转换数组中的每一个元素
  • 对于嵌套对象:遍历对象的所有属性,递归转换每个属性的值

完整代码实现

// 先定义你的目标Test类型(这里用示例结构,可根据实际需求修改)
type Test = { isConverted: true };

type ConvertToTest<T> = 
  // 1. 处理原始值:直接替换为Test类型
  T extends string | number | boolean 
    ? Test 
    // 2. 处理数组:提取元素类型并递归转换
    : T extends Array<infer ElementType> 
      ? Array<ConvertToTest<ElementType>> 
      // 3. 处理嵌套对象:遍历属性并递归转换每个值
      : T extends object 
        ? { [Property in keyof T]: ConvertToTest<T[Property]> } 
        // 兜底:题目已排除其他类型,这里保留兼容其他情况
        : T;

测试验证

用你给出的示例对象测试:

const before = { a: { c: '' }, b: [ '', { d: '' } ] } as const;

// 生成转换后的类型
type AfterType = ConvertToTest<typeof before>;

此时AfterType的类型会被TypeScript正确推导为:

{
  a: { c: Test };
  b: [Test, { d: Test }];
}

关键细节说明

  • 条件类型顺序:必须先判断原始值,再数组,最后对象。因为数组本质也是object的子类,如果先判断对象会导致数组被错误归类为普通对象处理。
  • infer关键字:用于提取数组的元素类型,让我们可以对数组内的每个元素执行递归转换。
  • 题目适配:由于你明确说明值仅为JSON可序列化的非null/Date/Symbol类型,所以我们不需要额外处理这些排除类型。如果后续需要兼容更多场景,可以在条件判断中添加对应的排除分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:54:39