You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:15:02