TypeScript中Map序列化后为空的原因咨询
问题原因解析
1. JSON.stringify的原生限制
JSON标准仅支持原始类型、普通对象、数组等结构,并不兼容ES6引入的Map类型。当调用JSON.stringify()时,它只会遍历对象的可枚举自有属性,但Map的键值对并非存储在对象自身的属性中,而是存放在内部的[[MapData]]隐藏槽位里,因此序列化时会被转换成空对象{}。
2. Firestore的存储类型约束
Firestore的文档数据仅支持JSON兼容的数据类型,同样不直接支持Map。当尝试存入Map时,Firestore会按照JSON序列化的逻辑处理,忽略Map内部的键值对,最终存储为空对象。
为什么调试和单元测试能看到值?
- 调试器会直接读取
Map内部的存储结构,能展示实际的键值对,不受JSON序列化规则影响。 - 单元测试是通过调用
Map的原生API(比如has('1.0.0')、get('1.0.0'))来验证,这些API直接操作Map的内部数据,因此能正确获取到值。
可行的解决方式
- 改用普通对象:像你已经做的那样,用
{ [key: string]: number }类型替代Map,普通对象完全兼容JSON和Firestore的要求,序列化和存储都不会有问题。 - 手动转换Map为对象(如果必须用Map):
- 序列化时自定义
replacer函数:JSON.stringify(updatedStats, (key, value) => { if (value instanceof Map) { return Object.fromEntries(value); } return value; }); - 存入Firestore前转换:
const firestoreData = { ...updatedStats, appVersions: Object.fromEntries(updatedStats.appVersions) }; // 再将firestoreData存入Firestore
- 序列化时自定义
内容的提问来源于stack exchange,提问作者Filled Stacks
相关产品推荐
相关产品推荐

