NextJS 13+Firebase+Axios+TS获取数据的类型错误求助
NextJS 13 API路由类型错误:'locationsData'不存在于GetLocationResponse类型
错误原因
- 类型层级定义错误:你定义的
GetLocationResponse把data作为内部属性,但Axios的响应结构本身就包含data字段(对应API返回的内容)。如果代码中直接访问response.locationsData而非response.data.locationsData,TypeScript会判定该属性不存在。 - 类型与API返回结构不匹配:如果API路由返回的不是
{ locationsData: LocationData[] }格式(比如直接返回数组),会导致类型定义和实际数据结构不兼容,触发错误。
解决方法
1. 修正类型定义
根据Axios的响应结构,正确定义类型:
// 定义API返回的核心数据结构 type LocationApiResponse = { locationsData: LocationData[]; }; // 方式1:利用Axios泛型指定返回的data类型(推荐) const response = await axios.get<LocationApiResponse>('/api/locations'); // 正确访问路径:response.data.locationsData // 方式2:定义完整的Axios响应类型 type GetLocationResponse = { data: LocationApiResponse; }; const response: GetLocationResponse = await axios.get('/api/locations'); // 访问路径同样是:response.data.locationsData
2. 确保API路由返回正确格式
检查pages/api/locations.tsx(Pages Router)或app/api/locations/route.ts(App Router)的返回结构,确保返回包含locationsData字段的对象:
// Pages Router 示例 import type { NextApiRequest, NextApiResponse } from 'next'; import { collection, getDocs } from 'firebase/firestore'; import { db } from '../../firebase-config'; // 定义LocationData类型 type LocationData = { id: string; name: string; // 补充你的数据字段 }; // 定义API返回的响应结构 type ApiResponse = { locationsData: LocationData[]; }; export default async function handler( req: NextApiRequest, res: NextApiResponse<ApiResponse> ) { const locationsCol = collection(db, 'locations'); const snapshot = await getDocs(locationsCol); // 将Firestore文档转换为目标格式 const locationsData = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })) as LocationData[]; // 返回包含locationsData的JSON res.status(200).json({ locationsData }); }
3. 组件中正确访问数据
在Locations.tsx中按照正确层级获取数据:
import axios from 'axios'; type LocationData = { id: string; name: string; // 对应你的数据字段 }; type LocationApiResponse = { locationsData: LocationData[]; }; export default async function Locations() { const response = await axios.get<LocationApiResponse>('/api/locations'); const locations = response.data.locationsData; return ( <div> {locations.map(location => ( <div key={location.id}>{location.name}</div> ))} </div> ); }
内容的提问来源于stack exchange,提问作者CatK
相关产品推荐
相关产品推荐

