使用useSWRInfinite时遭遇TypeScript类型错误:size与setSize属性不存在于SWRResponse类型
我碰到过好几次类似的TypeScript类型推断问题,尤其是在SWR的useSWRInfinite钩子上。你遇到的错误本质是TypeScript没有正确识别useSWRInfinite的返回类型,误把它当成了基础的SWRResponse(这是useSWR钩子的返回类型),而size和setSize是useSWRInfinite特有的属性。下面是几个肯定能帮你解决的方案:
1. 显式指定泛型类型,帮TypeScript"理清思路"
useSWRInfinite的类型推断很大程度上依赖你传入的getKey函数和fetcher的返回值,如果TypeScript没办法自动推断,手动指定泛型是最直接的办法。比如先定义你的数据类型,然后在调用钩子时明确指定:
// 先定义你的数据结构 interface Post { id: string; title: string; content: string; } // 调用useSWRInfinite时显式指定泛型 const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite<Post[], Error>( (pageIndex, previousPageData) => { // 你的getKey逻辑,比如分页请求的URL if (previousPageData && previousPageData.length === 0) return null; // 没有更多数据时停止请求 return `/api/posts?page=${pageIndex + 1}`; }, async (url) => { // 你的fetcher函数,确保返回的类型匹配Post[] const res = await fetch(url); return res.json(); }, // 可选的配置项 { initialSize: 1 } );
这样TypeScript就能准确识别返回的是SWRInfiniteResponse<Post[], Error>类型,而不是普通的SWRResponse,自然就能识别size和setSize了。
2. 检查getKey函数的类型是否正确
如果getKey函数的参数类型模糊,也会导致TypeScript推断错误。确保pageIndex是number类型,previousPageData的类型和你的数据类型一致。比如上面的例子里,previousPageData会被自动推断为Post[] | undefined,这就没问题。如果你的getKey逻辑比较复杂,可以手动标注参数类型:
const getKey = (pageIndex: number, previousPageData: Post[] | undefined) => { if (previousPageData?.length === 0) return null; return `/api/posts?page=${pageIndex + 1}`; }; const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite(getKey, fetcher);
3. 清理依赖缓存,确保类型定义是最新的
有时候即使你装了最新版的SWR和Next.js,旧的类型缓存或者依赖冲突也会导致问题。试试删除node_modules和锁文件,重新安装:
# npm用户 rm -rf node_modules package-lock.json npm install # yarn用户 rm -rf node_modules yarn.lock yarn install # pnpm用户 pnpm store prune pnpm install
4. 确认没有混淆useSWR和useSWRInfinite的返回类型
别不小心把useSWRInfinite的返回值赋值给了类型为SWRResponse的变量,比如:
// 错误示例:类型不匹配 const response: SWRResponse<Post[], Error> = useSWRInfinite(getKey, fetcher);
这种情况直接去掉显式类型标注就行,让TypeScript自动推断。
这些方案应该能解决你的类型错误,我之前用Next.js + SWR + TypeScript做无限加载时,就是靠显式指定泛型解决的这个问题。
内容的提问来源于stack exchange,提问作者Wordpressor

