TypeScript递归转换嵌套对象属性为数字函数失效问题
修复深度嵌套对象的属性值转数字递归函数
原函数处理多层嵌套对象时会丢失上层结构,核心问题在于递归时错误地将子对象的结果直接合并到父对象,而非保留当前层级的键关联。以下是修复后的完整实现:
type CastToNumber<T> = T extends string ? number : T extends null | undefined ? T : { [K in keyof T]: CastToNumber<T[K]> }; type StringMap = { [key: string]: any }; const castObjectValuesToNumber = function<T extends StringMap>(initialObj: T): CastToNumber<T> { const _castedObj: StringMap = {}; for (const [property, value] of Object.entries(initialObj)) { if (typeof value === "object" && value !== null) { // 递归处理子对象,并将结果赋值给当前属性键,保留层级结构 _castedObj[property] = castObjectValuesToNumber(value); } else { // 仅对字符串类型的值执行数字转换,其他类型保持原样 _castedObj[property] = typeof value === 'string' ? +value : value; } } return _castedObj as CastToNumber<T>; }
关键修改说明
- 移除
nestedProp参数:原参数逻辑错误地将当前属性名作为嵌套标识,导致上层结构被扁平化合并,直接移除后回归正常的层级递归逻辑。 - 保留层级关联:处理子对象时,不再使用扩展运算符合并结果,而是将递归后的子对象直接赋值给当前属性键,确保每个层级的结构都被完整保留。
- 增加null判断:由于
typeof null === 'object',额外排除null值避免不必要的递归调用。 - 严谨的类型转换:仅对字符串类型的值执行数字转换,其他类型(如数字、布尔值等)保持原样,避免意外转换。
测试验证
使用原问题中的army对象测试:
const army = { cavalry: { light: { quantity: "0", health: "0" }, heavy: { quantity: "0", health: "0" } }, infantry: { light: { quantity: "0", health: "0" }, heavy: { quantity: "0", health: "0" } }, magic: { light: { quantity: "0", health: "0" }, heavy: { quantity: "30", health: "0" } }, range: { light: { quantity: "0", health: "0" }, heavy: { quantity: "0", health: "0" } } }; const result = castObjectValuesToNumber(army);
修复后的result将完全匹配预期的层级结构,所有字符串类型的数值都会被正确转换为数字,同时保留cavalry、infantry等上层属性。
内容的提问来源于stack exchange,提问作者Cizia
相关产品推荐
相关产品推荐

