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
相关产品推荐
相关产品推荐

