实现类型安全的TypeScript对象数字字段转字符串函数(支持嵌套)
类型安全的递归数字转字符串函数实现
需求回顾
需要实现一个函数,接收任意嵌套结构的对象,将所有数字类型字段转换为字符串类型,同时让TypeScript能准确识别返回对象的结构和类型。
类型定义(核心)
首先定义递归的类型转换工具,用来描述数字转字符串后的类型结构:
type NumbersToString<T> = // 数字类型转为字符串 T extends number ? string : // 数组元素递归转换 T extends Array<infer U> ? Array<NumbersToString<U>> : // 对象属性递归转换 T extends object ? { [K in keyof T]: NumbersToString<T[K]> } : // 其他类型保持原样 T;
类型安全的函数实现
基于原有的lodash实现,添加类型断言和类型约束,确保TypeScript能正确推断返回类型:
import _ from 'lodash'; export const numbersToString = <T extends object>(obj: T): NumbersToString<T> => { // 深克隆原对象,避免修改输入 const clonedObj = _.cloneDeep(obj) as NumbersToString<T>; _.keys(clonedObj).forEach((key) => { const value = clonedObj[key as keyof typeof clonedObj]; if (_.isNumber(value)) { // 数字转字符串,断言为转换后的类型 clonedObj[key as keyof typeof clonedObj] = String(value) as NumbersToString<typeof value>; } else if (_.isArray(value)) { // 数组元素逐个处理,嵌套对象递归调用 clonedObj[key as keyof typeof clonedObj] = value.map(el => _.isObject(el) ? numbersToString(el) : el ) as NumbersToString<typeof value>; } else if (_.isObject(value)) { // 嵌套对象递归调用 clonedObj[key as keyof typeof clonedObj] = numbersToString(value) as NumbersToString<typeof value>; } }); return clonedObj; };
使用示例
// 定义测试对象类型 interface TestData { userId: number; username: string; stats: { posts: number; likes: number; tags: Array<{ id: number; name: string }>; }; } const rawData: TestData = { userId: 1001, username: "john_doe", stats: { posts: 25, likes: 1200, tags: [{ id: 5, name: "tech" }, { id: 8, name: "lifestyle" }] } }; const processedData = numbersToString(rawData); // processedData的类型会被TypeScript正确推断为: // { // userId: string; // username: string; // stats: { // posts: string; // likes: string; // tags: Array<{ id: string; name: string }>; // }; // }
关键说明
NumbersToString类型通过递归遍历,处理了对象、数组的嵌套结构,确保所有层级的数字类型都被转换为字符串。- 函数中使用类型断言
as NumbersToString<T>告诉TypeScript克隆后的对象结构,避免类型不匹配报错。 - 遍历对象键时,通过
key as keyof typeof clonedObj确保键的类型与对象结构匹配。
内容的提问来源于stack exchange,提问作者Kromel
相关产品推荐
相关产品推荐

