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

如何为处理任意结构数据的递归工具函数添加类型定义?

给递归结构处理函数parseData添加TypeScript类型定义

嘿,我来帮你搞定这个TypeScript类型定义的问题!你的parseData是典型的递归处理任意结构数据的函数,核心需求是让TypeScript能准确推断「输入和输出的结构完全对应」,同时支持你提到的所有类型(Object/Array/Number/String,还有布尔、null这类常见补充类型)。

第一步:定义输入和输出的递归类型

首先我们需要声明两个核心类型,用来约束输入范围并映射输出结构:

  • InputData:限定函数能接收的所有合法输入类型,涵盖基础类型和嵌套的数组/对象
  • ParsedData<T>:通过递归条件类型,把输入类型映射为对应的输出类型,确保结构完全匹配
// 定义允许的输入类型范围
type InputData = string | number | boolean | null | undefined | InputData[] | { [key: string]: InputData };

// 递归定义解析后的输出类型,和输入结构一一对应
type ParsedData<T extends InputData> = 
  T extends string ? string : // 如果字符串处理器会改类型(比如转Date),这里就改成Date
  T extends number ? number : // 同理,数字处理器若转字符串就改成string
  T extends boolean ? boolean :
  T extends null ? null :
  T extends undefined ? undefined :
  T extends InputData[] ? ParsedData<T[number]>[] : // 数组元素递归解析
  T extends { [key: string]: InputData } ? { [K in keyof T]: ParsedData<T[K]> } : // 对象属性递归解析
  never;

第二步:给parseData函数添加类型标注

把类型和函数实现结合起来,因为递归函数的自动类型推断有局限,我们用as ParsedData<T>辅助TypeScript识别返回类型:

function parseData<T extends InputData>(data: T): ParsedData<T> {
  // 处理数组:递归解析每个元素
  if (Array.isArray(data)) {
    return data.map(item => parseData(item)) as ParsedData<T>;
  }
  // 处理对象:递归解析每个属性
  else if (typeof data === 'object' && data !== null) {
    const result: Record<string, unknown> = {};
    for (const key in data) {
      if (Object.prototype.hasOwnProperty.call(data, key)) {
        result[key] = parseData(data[key]);
      }
    }
    return result as ParsedData<T>;
  }
  // 处理字符串:调用你的parseString处理器
  else if (typeof data === 'string') {
    // 替换成你的实际字符串处理逻辑,比如return parseString(data)
    return data.trim() as ParsedData<T>;
  }
  // 处理数字:调用你的parseNumber处理器
  else if (typeof data === 'number') {
    // 替换成你的实际数字处理逻辑,比如return parseNumber(data)
    return Math.round(data) as ParsedData<T>;
  }
  // 布尔、null、undefined直接返回(需要处理的话可以加对应分支)
  else {
    return data as ParsedData<T>;
  }
}

第三步:验证类型推断效果

写个测试用例就能看到,TypeScript会自动推断输出类型和输入结构完全一致:

const testInput = {
  username: "  jane_smith  ",
  age: 32.7,
  skills: ["react", "typescript"],
  status: {
    isVerified: true,
    lastUpdate: null
  }
};

const testOutput = parseData(testInput);
// testOutput的类型会被自动推断为:
// {
//   username: string; // 对应trim后的字符串
//   age: number;      // 对应取整后的数字
//   skills: string[]; // 每个元素都经过字符串处理
//   status: {
//     isVerified: boolean;
//     lastUpdate: null;
//   };
// }

灵活调整类型映射

如果某个处理器会改变数据类型(比如把日期字符串转成Date对象),只需要修改ParsedData<T>里对应的条件分支即可:

// 示例:字符串处理器返回Date类型
type ParsedData<T extends InputData> = 
  T extends string ? Date : // 这里把string改成Date
  // ... 其他分支保持不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:44:28