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

Axios未正确将含Map的响应反序列化为指定Schema类型问题

问题

我用Axios发送GET请求时,明明指定了包含Map的响应类型Schema,但返回的Map并没有被反序列化为Map实例。

API返回的JSON结构固定:

{
    "key1": {
        "key1": "val1",
        "key2": "val2"
    },
    "key2": {
        "key3": "val3",
        "key4": "val4"
    }
}

我的请求代码如下:

interface Schema {
  key1: Map<string, Map<string, string>>;
  key2: Map<string, Map<string, string>>;
}

function App() {
  axios.get<Schema>('http://127.0.0.1:5000/api').then(response => {
    console.log(response.data)
    console.log(response.data.key1.entries())
    })
    .catch(error => {
      console.error(error);
      throw error;
    });

  return (<div></div>);
}

export default App;

虽然console.log(response.data)看起来结构符合Schema,但调用response.data.key1.entries()时报错:

response.data.key1.entries is not a function
TypeError: response.data.key1.entries is not a function
    at http://localhost:3000/static/js/bundle.js:31:36

仔细看日志发现,响应里的内部映射其实是普通Object,不是Map实例。请问怎么确保key1和key2是Map类型,方便遍历条目?

解决方法

核心原因

JSON格式本身没有Map类型,Axios默认只会把JSON响应反序列化为普通JavaScript对象,TypeScript的泛型只是做编译时的类型校验,不会帮你把对象转换成Map实例。

具体方案

你需要手动把响应中的普通对象转换成Map,可通过以下两种方式实现:

1. 手动转换单个字段

在获取响应后,编写转换函数把嵌套对象转成Map:

// 把普通对象转成Map<string, string>
function objToStrMap(obj: Record<string, string>): Map<string, string> {
  return new Map(Object.entries(obj));
}

// 把嵌套对象转成Map<string, Map<string, string>>
function objToNestedMap(obj: Record<string, Record<string, string>>): Map<string, Map<string, string>> {
  const map = new Map<string, Map<string, string>>();
  for (const [key, value] of Object.entries(obj)) {
    map.set(key, objToStrMap(value));
  }
  return map;
}

// 请求回调中执行转换
axios.get<Record<string, Record<string, Record<string, string>>>>('http://127.0.0.1:5000/api')
  .then(response => {
    const data = {
      key1: objToNestedMap(response.data.key1),
      key2: objToNestedMap(response.data.key2)
    } as Schema;
    console.log(data.key1.entries()); // 现在可正常调用Map方法
  })
  .catch(error => {
    console.error(error);
    throw error;
  });

2. 自定义Axios响应转换器

如果多个请求都需要这种转换,可以全局配置Axios的响应转换器,自动把指定结构的对象转成Map:

// 复用上面定义的objToStrMap和objToNestedMap函数

// 扩展Axios配置,添加自定义响应转换器
axios.defaults.transformResponse = [
  ...(axios.defaults.transformResponse as Array<any>),
  function(data: any) {
    // 只转换符合目标结构的字段
    if (data.key1 && typeof data.key1 === 'object') {
      data.key1 = objToNestedMap(data.key1);
    }
    if (data.key2 && typeof data.key2 === 'object') {
      data.key2 = objToNestedMap(data.key2);
    }
    return data;
  }
];

// 之后的请求会自动完成转换
axios.get<Schema>('http://127.0.0.1:5000/api')
  .then(response => {
    console.log(response.data.key1.entries()); // 正常工作
  });

注意事项

  • TypeScript的泛型Schema只是编译时的类型提示,不会影响运行时的数据结构,所以转换后要手动断言类型(as Schema)来保证类型正确。
  • 如果API返回的键包含特殊字符(比如空格、连字符),用Map会比普通对象更合适,因为普通对象的键有语法限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:43:11