如何为处理任意结构数据的递归工具函数添加类型定义?
给递归结构处理函数
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
相关产品推荐
相关产品推荐

