Preact Query 的 AnyUseInfiniteQueryOptions:在泛型工具函数中接纳任意无限查询选项 Preact Query 的 AnyUseInfiniteQueryOptions在泛型工具函数中接纳任意无限查询选项【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/queryAnyUseInfiniteQueryOptions是tanstack/preact-queryTanStack Query 面向 Preact 的官方适配层为useInfiniteQuery一族 Hook 提供的类型擦除型别名。它将 UseInfiniteQueryOptions 的 5 个类型参数全部放宽为any使开发者能编写接收任意无限查询选项的辅助函数、混入函数与选项工厂而无需复制完整泛型签名。读完本文你将掌握该别名在源码中的精确定义、适用场景、它与底层InfiniteQueryObserverOptions的继承关系以及何时应放弃any回退到完整泛型以保住类型安全。一、别名定义一行代码背后的类型架构在 preact-query/src/types.ts 中该别名被定义如下/** * {link UseInfiniteQueryOptions} with all type parameters set to any, useful when the specific types arent * relevant, e.g. when accepting options for any query in a helper function. */ export type AnyUseInfiniteQueryOptions UseInfiniteQueryOptions any, any, any, any, any 要点解析它不是一个运行时 API而是一个纯类型别名。通过 preact-query/src/index.ts 中的export * from ./types随包导出实际使用时应写import type { AnyUseInfiniteQueryOptions } from tanstack/preact-query编译后该类型被完全擦除零运行时开销。它是UseInfiniteQueryOptions的全any实例化。换句话说凡是需要UseInfiniteQueryOptions的位置只要不关心具体数据类型都可以直接写AnyUseInfiniteQueryOptions避免了在几十个参数位置反复声明 5 个泛型形参的样板代码。源文件顶部声明/* istanbul ignore file */见 types.ts说明此文件是纯类型/声明层不属于单元测试覆盖范围进一步印证它是面向 TS 类型系统的契约描述而非运行逻辑。二、类型基座UseInfiniteQueryOptions 的 5 个泛型参数要理解any究竟放宽了什么先看基接口 UseInfiniteQueryOptions 的完整签名export interface UseInfiniteQueryOptions TQueryFnData unknown, TError DefaultError, TData InfiniteDataTQueryFnData, TQueryKey extends QueryKey QueryKey, TPageParam unknown, extends OmitKeyof InfiniteQueryObserverOptions TQueryFnData, TError, TData, TQueryKey, TPageParam , suspense { /** * Set this to false to unsubscribe this observer from updates to the query cache. * * defaultValue true */ subscribed?: boolean }5 个类型参数及其语义注释出自源码本身类型参数默认值含义TQueryFnDataunknownqueryFn解析出的单页数据的类型TErrorDefaultErrorqueryFn可能抛出的错误类型TDataInfiniteDataTQueryFnDataselect运行后data的类型默认是所有已拉取页面及其分页参数的整体形态pagespageParamsTQueryKeyQueryKeyqueryKey的类型约束必须继承自QueryKeyTPageParamunknown传给queryFn以拉取某一页的页码参数类型该接口有两条值得注意的派生路径继承自tanstack/query-core的InfiniteQueryObserverOptions并通过OmitKeyof剔除suspense。原因在源码注释中写得很清楚Preact 适配层由你调用的是哪个 Hook来推导 Suspense 语义而非暴露suspense选项对比见preact-query中useInfiniteQuery与useSuspenseInfiniteQuery的拆分。额外增加了 Preact 特有的subscribed?: boolean默认true。将其设为false可让该 observer 退订来自 query cache 的更新通知。这是 使用 useInfiniteQuery 的加载更多模式 等场景的选项类型里都会携带的字段。AnyUseInfiniteQueryOptions就是把上表的 5 个槽位全部填入any的结果因而它可以接受任何形式的 queryKey、任何页面类型、任何错误类型与任何页码参数的无限查询配置。三、为何需要全 any别名面向辅助函数的类型设计在深入泛型的代码里一处常见痛点是当编写一个自己并不真正关心数据形态的工具函数例如把一组公共选项混入各种无限查询、封装日志/指标上报、在组件库中转发 options时被迫写出带 5 个类型参数的巨型签名会让实现变得难以阅读且函数内部处处面临未推导的泛型约束。官方注释点明了设计意图types.tsuseful when the specific types arent relevant, e.g. when accepting options for any query in a helper function.典型写法import type { AnyUseInfiniteQueryOptions } from tanstack/preact-query import { useInfiniteQuery } from tanstack/preact-query // 辅助函数为任意无限查询注入统一的失败重试策略 function withRetryPolicy( options: AnyUseInfiniteQueryOptions, ): AnyUseInfiniteQueryOptions { return { retry: 3, retryDelay: (attempt) Math.min(1000 * 2 ** attempt, 30_000), staleTime: 60_000, ...options, } } function Feed() { // 普通、Suspense 之外的常规场景均可透传 const query useInfiniteQuery( withRetryPolicy({ queryKey: [feed], queryFn: ({ pageParam }) fetchFeed(pageParam), initialPageParam: 0, getNextPageParam: (lastPage) lastPage.nextCursor, }), ) // ... }由于UseInfiniteQueryOptions是结构性接口类型withRetryPolicy返回的对象仍保有 queryKey/queryFn 等运行时字段可以被useInfiniteQuery的重载直接消费——any只放宽编译期检查不影响运行期行为。从实现看useInfiniteQuery 的实现签名收窄为options: UseInfiniteQueryOptions后委托给useBaseQuery(options, InfiniteQueryObserver, queryClient)因此选项对象最终流向 query-core 的InfiniteQueryObserver其底层契约见 docs/reference/InfiniteQueryObserver.md。四、相似别名族同一模式在多条 API 线上的复用AnyUseInfiniteQueryOptions并非孤例。在 preact-query/src/types.ts 中可以看到整个类型层遵循一致的基接口 Any 别名组合模式别名展开目标源码位置AnyUseBaseQueryOptionsUseBaseQueryOptionsany, any, any, any, anytypes.tsAnyUseQueryOptionsUseQueryOptionsany, any, any, anytypes.tsAnyUseInfiniteQueryOptionsUseInfiniteQueryOptionsany, any, any, any, anytypes.tsAnyUseSuspenseQueryOptionsUseSuspenseQueryOptionsany, any, any, anytypes.tsAnyUseSuspenseInfiniteQueryOptionsUseSuspenseInfiniteQueryOptionsany, any, any, any, anytypes.ts其中与本文最相关的是AnyUseSuspenseInfiniteQueryOptions——它是useSuspenseInfiniteQuery的选项类型别名对应 UseSuspenseInfiniteQueryOptions。如果你的工具函数需要同时服务普通与Suspense两条 Hook 线就会体会到这种对称命名的价值按 Hook 名对应选取别名即可。值得注意的类型边界同样来自源码注释UseSuspenseInfiniteQueryOptions相比UseInfiniteQueryOptions额外剔除了queryFn不允许值为skipToken、enabled、throwOnError与placeholderData——Suspense Hook 无法渲染禁用/占位状态types.ts。非 Suspense 的UseInfiniteQueryOptions仍允许queryFn: skipToken用于参数未就绪时类型安全地禁用查询见 useInfiniteQuery.ts 的postId示例。因此在为工具函数选型时先确认目标 Hook 是普通还是 Suspense 版本再选择对应的 Any 别名避免把 Suspense 不允许的字段如enabled带入不可用的类型表面。五、类型安全边界何时该换回完整泛型AnyUseInfiniteQueryOptions的本质是把类型检查责任后移。用它声明的函数对调用方几乎不做静态约束因此丢失了显式泛型签名能提供的提示与纠错能力。从 react-query/src/types.ts 可以看到React 版适配层维护着完全相同的别名——这是 TanStack Query 各框架适配层的既定 API 表面而非 Preact 特有的权宜之计。实务建议跨组件/包共享且数据形态明确的查询优先用完整泛型保留类型。例如自定义封装时通过UseInfiniteQueryOptionsTQueryFnData, TError, TData, TQueryKey, TPageParam显式声明让调用方的queryKey变更能立刻触发编译期错误。仅在选项透明转发/聚合层使用AnyUseInfiniteQueryOptions例如选项注入器、埋点/上报包装、以及对接queryClient.infiniteQuery与usePrefetchInfiniteQuery的共享选项工厂。这类位置通常既不需要读取泛型承载的语义也难以在编译期预测未来会被哪类页面数据消费。若需要任何查询的配置但又有最小约束可以考虑用UseInfiniteQueryOptionsunknown, DefaultError, InfiniteDataunknown, QueryKey, unknown这类带默认值的显式写法语义上等价而更可读Any别名则更契合追求极简签名的场景。六、小结定义位置preact-query/src/types.ts类型别名编译期擦除无运行时开销基座接口UseInfiniteQueryOptions其完整字段解析可见对应 interface 文档底层来源tanstack/query-core的InfiniteQueryObserverOptions剔除suspense Preact 特有subscribed字段核心用途在工具函数/混入/组件库中接受任意无限查询的选项对象同族对照AnyUseQueryOptions、AnyUseSuspenseInfiniteQueryOptions等types.ts 起连续定义与 React 版实现react-query/src/types.ts保持一致。把AnyUseInfiniteQueryOptions当作类型表面的默认参数来理解当你的函数把选项当作不透明数据转发时它让你的代码保持整洁当选项的语义真正影响调用方安全时请回到完整泛型。这正是 TanStack Query 类型层默认宽松、按需收紧哲学的缩影。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考