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
相关产品推荐
相关产品推荐

