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

在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,
    };
  });
}

错误原因分析

你碰到的类型问题大概率来自这两个点:

  1. pages数组可能为空:InfiniteData里的pages是数组,但当查询还没拿到任何数据时,pages可能是空数组,此时pages[0]就是undefined。虽然你用了可选链?.,但还要确认IListItems类型里是否把filterCount定义为FilterCountData | undefined。
  2. 返回结构的类型匹配问题:你把多页数据合并成了单页结构,但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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:47:58