如何对包含Map、Set的复杂TypeScript对象进行深度JSON序列化
解决TypeScript对象包含Map/Set时的JSON序列化问题
你的resultAnalytic对象里用到了Map、Set这类JSON标准不支持的数据结构,直接调用JSON.stringify()会把它们序列化成空对象{},导致关键数据丢失。要完成正确的序列化,需要自定义一个replacer函数来处理这些特殊类型。
1. 实现自定义Replacer函数
这个函数会在序列化过程中拦截每个值,把Map和Set转换成JSON能识别的结构:
function analyticReplacer(key: string, value: unknown): unknown { // 将Map转换为带类型标记的对象,保留键值对数组 if (value instanceof Map) { return { _type: 'Map', entries: Array.from(value.entries()) }; } // 将Set转换为带类型标记的对象,保留值数组 if (value instanceof Set) { return { _type: 'Set', values: Array.from(value.values()) }; } // 其他原生JSON支持的类型直接返回 return value; }
2. 执行序列化
调用JSON.stringify时传入这个replacer函数,就能得到完整的可存储JSON字符串:
const analyticMetadata = JSON.stringify(resultAnalytic, analyticReplacer, 2); // analyticMetadata就是可以写入文档的元数据字符串
3. (可选)解析回原对象结构
如果之后需要把存储的JSON字符串还原成TypeScript对象,需要对应实现一个reviver函数,把带标记的结构转回Map和Set:
function analyticReviver(key: string, value: unknown): unknown { if (typeof value === 'object' && value !== null) { const typedValue = value as { _type?: string }; // 还原Map if (typedValue._type === 'Map') { return new Map((value as { entries: [unknown, unknown][] }).entries); } // 还原Set if (typedValue._type === 'Set') { return new Set((value as { values: unknown[] }).values); } } return value; } // 解析示例 const parsedAnalytic = JSON.parse(analyticMetadata, analyticReviver) as ExportAnalyticsData;
注意事项
- 对于
groups.groupsWithVideo中的Set<Entity>,只要Entity是普通的JavaScript/TypeScript对象(没有特殊方法或不可枚举属性),就能被正常序列化和还原;如果Entity有自定义逻辑,可能需要在replacer/reviver中额外处理。 - 数组、普通对象、布尔值、数字、字符串这些原生类型不需要额外处理,JSON会自动识别。
内容的提问来源于stack exchange,提问作者Rue Vitale
相关产品推荐
相关产品推荐

