You need to enable JavaScript to run this app. 如何正确将C# Dictionary传递并转换为TypeScript Map类型
优惠活动
大模型
产品
解决方案
定价
更多

如何正确将C# Dictionary传递并转换为TypeScript Map类型

问题原因
  1. C#的Dictionary序列化为JSON时默认会转换为普通键值对对象,不会输出Map兼容的可迭代结构
  2. Angular HttpClient的泛型声明仅用作TypeScript编译期的类型提示,不会做实际运行时的类型转换。你声明get<Map<number, number>>仅为编译期类型伪装,实际拿到的还是普通JS对象,没有挂载Map的原型方法,所以调用values()会报错
  3. 普通JS对象默认不是可迭代类型,直接传入Map构造函数自然会报object is not iterable的错误

前端侧解决方案(无需修改后端接口)

步骤1:修正接口请求的类型声明

把请求的返回类型改为和实际返回结构匹配的Record<number, number>,避免类型误导:

getReportsUsage() {
  return this.http.get<Record<number, number>>(`${environment.apiUrl}/stats/reportsUsage`, {
    headers: new HttpHeaders({
      'Accept': 'application/json'
    }),
    withCredentials: true
  });
}

GET请求没有请求体,不需要设置Content-Type头,直接删除即可

步骤2:拿到返回值后手动转换为Map

用Object.entries把普通对象转换为[key, value]格式的二维数组,再传入Map构造函数即可。如果需要严格保证键的类型为number,可以手动做一次类型转换:

this.statsService.getReportsUsage().subscribe(data => {
  // 严格保证键为number的写法,匹配你定义的Map<number, number>类型
  this.reportsUsage = new Map(
    Object.entries(data).map(([key, value]) => [Number(key), value])
  );

  // 之后就可以正常调用Map的所有方法
  console.log(this.reportsUsage);
  console.log(this.reportsUsage.values());
  console.log(typeof(this.reportsUsage));
});

可选后端适配方案(无需前端转换)

如果不想在前端做转换,也可以修改后端接口的返回结构,把Dictionary转为键值对集合后再返回:

[HttpGet("reportsUsage")]
public IActionResult GetReportsUsage()
{
    IDictionary<int, int> test = new Dictionary<int, int>();
    test.Add(1, 20);
    test.Add(2, 30);
    // 省略其他添加逻辑

    // 转换为键值对数组输出
    return Ok(test.Select(kv => new object[] {kv.Key, kv.Value}));
}

此时前端拿到的就是可迭代的二维数组,可以直接初始化Map:

this.reportsUsage = new Map(data as [number, number][]);

内容的提问来源于stack exchange,提问作者Whistler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 20:15:05