TypeScript中解析API响应时,MapDetails的products字段无法正确转为Map的问题求助
TypeScript中解析API响应时,MapDetails的products字段无法正确转为Map的问题求助
问题描述
我在TypeScript里调用API发送GET请求后,没法正确解析返回的响应数据。MapDetails里的products字段总是被解析成普通对象,而不是我定义的Map结构,有没有大佬能帮忙解决这个问题?
API返回的JSON响应:
{ "New Arrivals": { "url": "https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?q=80\u0026w=2574\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "filters": {"category":"New Arrivals","gender":"Unisex"}, "products": { "Men": { "Accessories":{"category":"All Accessories","gender":"Men"}, "Gifts":{"category":"Gifts","gender":"Men"} }, "Women": { "Accessories":{"category":"All Accessories","gender":"Women"}, "Gifts":{"category":"Gifts","gender":"Women"} } } }, "Women": { "url": "https://plus.unsplash.com/premium_photo-1675186049409-f9f8f60ebb5e?q=80\u0026w=2574\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "filters": {"category":"All Products","gender":"Women"}, "products": { "Accessories": { "All Accessories":{"category":"All Accessories","gender":"Men"}, "Bags":{"category":"Bags","gender":"Men"} }, "Clothes": { "All Clothes":{"category":"All Clothes","gender":"Women"}, "Bottoms":{"category":"Bottoms","gender":"Women"} } } } }
我当前的解析代码:
fetch('http://localhost:8080/') .then(response => response.json()) .then(parsed => new Map<string, MapDetails>(Object.entries(parsed)))
我的TypeScript接口定义:
export interface ShopDetails { category: string; gender: string; } export interface MapDetails { url: string; filters: ShopDetails; products : Map<string, Map<string, ShopDetails>> }
解决方案
问题根源很简单:JSON本身没有Map这个数据类型,response.json()只会把JSON里的对象转成普通的JS对象。你现在只处理了顶层的对象转Map,但内层的products嵌套对象根本没被处理,自然还是普通对象。
我们可以写一个递归函数来把嵌套对象转成对应的Map结构,然后在解析时针对性处理products字段:
- 先定义递归转换函数
// 递归把嵌套对象转成Map function objectToNestedMap(obj: any): Map<string, any> { const map = new Map<string, any>(); for (const [key, value] of Object.entries(obj)) { // 如果值是对象(排除数组和null),就递归转换;否则直接存入 if (typeof value === 'object' && value !== null && !Array.isArray(value)) { map.set(key, objectToNestedMap(value)); } else { map.set(key, value); } } return map; }
- 修改解析逻辑,处理每个
MapDetails的products字段
fetch('http://localhost:8080/') .then(response => response.json()) .then(parsed => { const resultMap = new Map<string, MapDetails>(); for (const [key, details] of Object.entries(parsed)) { // 把products的嵌套对象转成符合类型的Map const processedDetails: MapDetails = { ...details, products: objectToNestedMap(details.products) as Map<string, Map<string, ShopDetails>> }; resultMap.set(key, processedDetails); } // 这里就可以用转换好的resultMap了 return resultMap; })
补充说明
- 递归函数
objectToNestedMap会逐层遍历对象,遇到嵌套对象就继续转换,这样products里的两层嵌套结构都会被转成Map<string, Map<string, ShopDetails>>,完全匹配你的接口定义。 - 用
as Map<string, Map<string, ShopDetails>>是类型断言,告诉TypeScript转换后的结构符合我们的接口要求,避免不必要的类型报错。
备注:内容来源于stack exchange,提问作者Grant
相关产品推荐
相关产品推荐

