type DeepReadonly<T> = T extends Function
? T
: T extends Array<infer U>
? DeepReadonlyArray<U>
: T extends object
? DeepReadonlyObject<T>
: T;
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
interface DeepReadonlyObject<T> {
readonly [P in keyof T]: DeepReadonly<T[P]>;
}
function deepTraverseAndTransform<T, U extends keyof T, V>(
data: DeepReadonly<T>,
typeKey: U,
callback: (value: T[U]) => V
): T {
return JSON.parse(
JSON.stringify(data),
(key, value) => {
if (key === typeKey) {
return callback(value);
}
return value;
}
) as T;
}
// 示例用法
const complexData = {
data: [[{ value: 1 }, { value: 2 }], [{ value: 3 }]]
};
const newComplexData = deepTraverseAndTransform(
complexData,
'value',
(value) => value * 2
);
console.log(newComplexData);
代码解释
- 类型定义:
DeepReadonly
是一个递归类型别名,用于将任何嵌套的数组或对象转换为只读类型,以确保在遍历过程中不会意外修改原始数据结构。
DeepReadonlyArray
和 DeepReadonlyObject
是辅助类型,用于更清晰地定义数组和对象的只读结构。
deepTraverseAndTransform
函数:
- 接收三个参数:
data
:要遍历的复杂数据结构,类型为 DeepReadonly<T>
,确保数据结构只读。
typeKey
:用于指定要操作的值的键名,类型为 U extends keyof T
,确保键名在数据结构中存在。
callback
:用于定义对符合特定类型的值进行操作的回调函数,类型为 (value: T[U]) => V
,返回操作后的值。
- 使用
JSON.stringify
和 JSON.parse
结合 replacer
函数来遍历和转换数据。replacer
函数在遇到指定的 typeKey
时,调用 callback
对值进行操作,其他情况下返回原始值。最后将解析后的结果转换回 T
类型。
- 示例用法:
- 定义了一个
complexData
作为示例数据结构。
- 调用
deepTraverseAndTransform
函数,对 value
键对应的值进行乘以2的操作,并输出结果。
性能优化
- 避免深度递归:使用
JSON.stringify
和 JSON.parse
避免了手动深度递归遍历,减少了栈溢出的风险,并且在处理复杂嵌套结构时性能相对稳定。
- 只读类型:通过
DeepReadonly
类型确保原始数据不会被意外修改,减少潜在的错误,从整体上提升程序性能和稳定性。