React-Query与UseQueryResult的TypeScript类型错误解决咨询
解决React Query自定义Hook的TypeScript类型错误
错误原因分析
你遇到的错误有两个核心原因:
- 错误解构返回值:
useOrderItemsForCardsInList返回的是React Query的UseQueryResult对象,该对象没有orderItems属性——接口返回的orderItems嵌套在UseQueryResult的data字段中。 - 类型不明确:
- 未定义API返回数据的类型,导致
data为any,TypeScript无法推断结构。 - 当
listID为空时,Hook返回undefined,导致类型包含undefined分支,解构时触发类型错误。
- 未定义API返回数据的类型,导致
分步修复方案
1. 定义API返回数据的TypeScript类型
先明确接口返回的数据结构,创建对应的类型定义:
// 定义单个OrderItem的结构,根据实际API字段调整 interface OrderItem { id: string; cardId: string; position: number; // 其他字段... } // 定义接口返回的整体结构 interface OrderItemsResponse { orderItems: OrderItem[]; }
2. 修正数据请求函数
为请求函数添加返回类型,并处理HTTP错误(避免解析失败的响应):
async function getOrderItemsForCardsInList(listID: string): Promise<OrderItemsResponse> { const token = await getToken(); const response = await fetch(`${basePath}/lists/${listID}/order_items/`, { method: 'GET', headers: getTokenAuthHeaders(token) }); // 处理HTTP错误状态码 if (!response.ok) { throw new Error(`Failed to fetch order items: ${response.statusText}`); } // 断言返回类型,让TypeScript识别结构 return response.json() as Promise<OrderItemsResponse>; }
3. 优化自定义Hook
修改Hook,确保始终返回UseQueryResult类型(避免返回undefined),并通过泛型明确类型:
export default function useOrderItemsForCardsInList(listID: string | null) { return useQuery<OrderItemsResponse, Error>( // 查询键,确保listID为空时键唯一 ['listOrderItems', listID], // 仅当listID存在时执行请求 () => getOrderItemsForCardsInList(listID!), { // 启用条件:listID不为空时才触发查询 enabled: !!listID, } ); }
这里用enabled选项替代原有的if判断,既控制查询时机,又保证Hook始终返回合法的UseQueryResult对象。
4. 正确在组件中消费Hook
在组件中通过data字段获取接口返回的orderItems,并处理可能的空值:
export default function CardsListFetch({ listID }: { listID: string }) { const { isLoading, isError, error, data: cardsData } = useCardsForList(listID); // 获取orderItems查询结果 const { data: orderItemsData } = useOrderItemsForCardsInList(listID); // 使用可选链访问orderItems,避免空值报错 const pagesArray = usePaginateCardsInList(orderItemsData?.orderItems, cardsData); // 处理加载和错误状态 if (isLoading) return <div>加载中...</div>; if (isError) return <div>错误:{error?.message}</div>; // 确保数据存在后再渲染 if (!cardsData || !orderItemsData) return <div>无数据</div>; return ( // 你的组件渲染内容 ); }
内容的提问来源于stack exchange,提问作者Daniel Corona
相关产品推荐
相关产品推荐

