TypeScript中如何使用复杂类型作为Map的键?
问题根本原因
TypeScript是JavaScript的类型超集,运行时的Map行为完全遵循JS规则:Map的键比较使用严格相等(===),对于对象类型的键,比较的是内存引用地址而非对象的属性值。你两次传入的Key类型对象哪怕section和index的值完全一致,只要是不同的对象实例,就会被判定为不同的键,所以get时会返回undefined。另外你代码中的cont val属于笔误,正确写法为const val。
可行解决方案
方案1:序列化复合键为字符串(最常用、成本最低)
直接把两个属性拼接为唯一字符串作为键,运行时开销极低,实现简单:
type Key = { section: number, index: number } // 这里替换为你实际的Record类型定义 type YourRecord = any; const map = new Map<string, YourRecord>(); // 存值 const key = { section: 1, index: 2 }; map.set(`${key.section}-${key.index}`, yourRecordObj); // 取值 const val = map.get(`${myKey.section}-${myKey.index}`);
如果要保留类型安全,你可以封装一个自定义Map类隐藏序列化逻辑,对外暴露的接口完全符合你原本的使用习惯:
class CompositeKeyMap { private innerMap = new Map<string, YourRecord>(); private serialize(key: Key): string { return `${key.section}-${key.index}`; } set(key: Key, value: YourRecord): void { this.innerMap.set(this.serialize(key), value); } get(key: Key): YourRecord | undefined { return this.innerMap.get(this.serialize(key)); } has(key: Key): boolean { return this.innerMap.has(this.serialize(key)); } delete(key: Key): boolean { return this.innerMap.delete(this.serialize(key)); } } // 使用时和原生Map体验完全一致,全程类型安全 const map = new CompositeKeyMap(); map.set({ section: 1, index: 2 }, yourRecordObj); const val = map.get({ section: 1, index: 2 }); // 可正确获取到值
方案2:复用同一对象引用(仅适用特定场景)
如果你的Key实例可以全局复用,每次存、取操作都传入同一个对象实例,也可以直接用原生Map。但这种方式限制非常多,很容易因为意外创建新对象实例导致取值失败,不推荐通用场景使用。
内容的提问来源于stack exchange,提问作者sak
相关产品推荐
相关产品推荐

