在useInfiniteQuery中使用Select转换API响应格式时遇到TypeScript类型错误
在useInfiniteQuery中使用Select转换API响应格式时遇到TypeScript类型错误
看起来你在用React Query的useInfiniteQuery做响应格式转换时,在获取filterCount的地方碰到了类型报错。我先理清楚你的代码场景,再一步步帮你解决问题。
你的现有代码片段
Custom Hook调用
const { data } = useListInfiniteQuery({ searchText: SearchText, dateRange: dateRange, select: getListItems, });
Select转换函数
function getListItems({ pageParams, pages, }: InfiniteData<IListItems>): InfiniteData<IListItems> { const allItems = pages.flatMap((page) => page.items); const filterCount = transformFilterCount(pages[0]?.filterCount);// 这里出现错误 return { pageParams, pages: [ { items: allItems, filterCount, }, ], }; }
相关类型与转换函数
export type FilterCountData = Record<string, Record<string, number>>; export interface IFilterOption { label: string; count: number; value: string; } export interface IFilterCategory { name: string; options: IFilterOption[]; } function transformFilterCount( filterCountData: FilterCountData | undefined, ): IFilterCategory[] { if (!filterCountData) { return []; } return Object.keys(filterCountData).map((categoryName) => { const options = Object.entries(filterCountData[categoryName]).map(([value, count]) => ({ label: value, count, value, })); return { name: categoryName, options, }; }); }
错误原因分析
你碰到的类型问题大概率来自这两个点:
- pages数组可能为空:
InfiniteData里的pages是数组,但当查询还没拿到任何数据时,pages可能是空数组,此时pages[0]就是undefined。虽然你用了可选链?.,但还要确认IListItems类型里是否把filterCount定义为FilterCountData | undefined。 - 返回结构的类型匹配问题:你把多页数据合并成了单页结构,但
InfiniteData<IListItems>要求pages是IListItems[],得确保合并后的对象完全符合IListItems的类型定义(必须包含items和filterCount)。
解决方案
方案1:完善空值检查与兜底逻辑
先判断pages是否有数据,再去取filterCount,避免空数组访问的类型问题:
function getListItems({ pageParams, pages, }: InfiniteData<IListItems>): InfiniteData<IListItems> { const allItems = pages.flatMap((page) => page.items); // 先判断pages是否有数据,没有的话直接传undefined给转换函数 const filterCountData = pages.length > 0 ? pages[0].filterCount : undefined; const filterCount = transformFilterCount(filterCountData); return { pageParams, pages: [ { items: allItems, filterCount, }, ], }; }
方案2:确保IListItems类型定义正确
检查你的IListItems接口是否正确声明了filterCount字段:
// 替换YourItemType为你实际的列表项类型 export interface IListItems { items: YourItemType[]; filterCount?: FilterCountData; // 标记为可选,符合API返回的可能情况 }
方案3:优化空数据场景的完整处理
如果希望在没有分页数据时返回一个规范的空结构,可以再加一层判断:
function getListItems({ pageParams, pages, }: InfiniteData<IListItems>): InfiniteData<IListItems> { if (pages.length === 0) { return { pageParams, pages: [{ items: [], filterCount: [] }], }; } const allItems = pages.flatMap((page) => page.items); const filterCount = transformFilterCount(pages[0].filterCount); return { pageParams, pages: [ { items: allItems, filterCount, }, ], }; }
这样处理后,TypeScript就不会再因为空值访问或类型不匹配而报错了。
备注:内容来源于stack exchange,提问作者Arpitha
相关产品推荐
相关产品推荐

