ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入解析 Svelte Query 的 CreateInfiniteQueryResult 类型:createInfiniteQuery 返回值的完整指南

深入解析 Svelte Query 的 CreateInfiniteQueryResult 类型:createInfiniteQuery 返回值的完整指南 深入解析 Svelte Query 的 CreateInfiniteQueryResult 类型createInfiniteQuery 返回值的完整指南【免费下载链接】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/queryCreateInfiniteQueryResult是 TanStack Query 中 Svelte 适配层tanstack/svelte-query为createInfiniteQuery组合式 API 定义的返回结果类型别名。它本质上是对tanstack/query-core中InfiniteQueryObserverResult的再导出通过它Svelte 组件可以在类型安全的前提下访问无限查询的分页数据、加载状态以及fetchNextPage/fetchPreviousPage等分页控制能力。阅读本文后你将掌握该类型的完整字段语义、判别联合discriminated union的结构化状态机以及如何用 TypeScript 精确推导分页加载中的各种 UI 状态。类型定义一行别名的背后是完整的查询结果契约在 packages/svelte-query/src/types.ts:68 中CreateInfiniteQueryResult的定义极简/** Result from createInfiniteQuery */ export type CreateInfiniteQueryResult TData unknown, TError DefaultError, InfiniteQueryObserverResultTData, TError它没有自己实现任何逻辑而是将TData与TError两个泛型参数透传给 query-core 的InfiniteQueryObserverResult。这种设计体现了 Svelte 适配层的定位框架适配层只负责把 query-core 的通用能力以 Svelte 响应式Accessor的形式暴露出来类型契约则完全复用核心层从而保证各框架React Query、Vue Query、Svelte Query 等行为与类型的一致性。该类型别名与createInfiniteQuery函数的返回类型一一对应函数签名位于 packages/svelte-query/src/createInfiniteQuery.ts:152export function createInfiniteQuery TQueryFnData, TError DefaultError, TData InfiniteDataTQueryFnData, TQueryKey extends QueryKey QueryKey, TPageParam unknown, ( options: AccessorCreateInfiniteQueryOptions..., queryClient?: AccessorQueryClient, ): CreateInfiniteQueryResultTData, TError类型参数详解参数默认值说明TDataunknown查询成功后data字段的最终数据类型。对于createInfiniteQuery而言data始终是InfiniteDataTQueryFnData结构包含pages与pageParams两个数组因此在实际调用中TData通常由函数签名推导为InfiniteDataTQueryFnData而非字面默认值unknownTErrorDefaultError查询失败时error字段携带的错误对象类型DefaultError本身也是一个可扩展的泛型默认值定义在 packages/query-core/src/types.ts:45export interface Register { // defaultError: Error // queryMeta: Recordstring, unknown // mutationMeta: Recordstring, unknown // queryKey: ReadonlyArrayunknown // mutationKey: ReadonlyArrayunknown } export type DefaultError Register extends { defaultError: infer TError } ? TError : Error从源码结构可以看出默认错误类型是Error但你可以通过 TypeScript 的 module augmentation 扩展Register接口来全局覆盖默认错误类型——这也是 TanStack Query 官方支持的全局类型注册机制。当项目中所有请求都抛出同一类自定义错误例如带业务码的ApiError时扩展Register.defaultError即可让CreateInfiniteQueryResult的TError参数自动推导为该项目统一错误类型无需在每个组件里手动标注泛型。底层本质五种状态组成的判别联合类型CreateInfiniteQueryResult的真正威力来自 query-core 的InfiniteQueryObserverResultpackages/query-core/src/types.ts:1058export type InfiniteQueryObserverResult TData unknown, TError DefaultError, | DefinedInfiniteQueryObserverResultTData, TError | InfiniteQueryObserverLoadingErrorResultTData, TError | InfiniteQueryObserverLoadingResultTData, TError | InfiniteQueryObserverPendingResultTData, TError | InfiniteQueryObserverPlaceholderResultTData, TError它是一个判别联合discriminated union判别字段是statuspending | error | success与其他布尔状态标志的组合。联合中的每个成员接口都以status为判别键TypeScript 会在if/switch分支收窄后自动推导出该分支下data、error等字段的精确类型联合成员statusdataerror关键标志InfiniteQueryObserverPendingResultpendingundefinednullisPending: trueInfiniteQueryObserverLoadingResultpendingundefinednullisPending: true、isLoading: trueInfiniteQueryObserverLoadingErrorResulterrorundefinedTErrorisLoadingError: trueInfiniteQueryObserverRefetchErrorResulterrorTData旧数据保留TErrorisRefetchError: trueInfiniteQueryObserverSuccessResultsuccessTDatanullisSuccess: trueInfiniteQueryObserverPlaceholderResultsuccessTDatanullisPlaceholderData: true各成员接口逐一定义在 packages/query-core/src/types.ts:946 至 packages/query-core/src/types.ts:1049。借助判别联合Svelte 模板中的{#if query.isPending}、{:else if query.isError}、{:else}分支不仅能正确渲染还能让query.data、query.error在对应分支获得正确的非空类型从根本上杜绝访问可能为undefined的data这类运行时错误。状态标志的语义边界通用字段继承自QueryObserverBaseResultpackages/query-core/src/types.ts:667以下是开发中最常用的核心字段及其精确语义status: pending | error | success查询的粗粒度状态isPending/isError/isSuccess是对应的派生布尔值isLoading首次获取正在进行中等价于isFetching isPending注意isInitialLoading已被标记为 deprecatedpackages/query-core/src/types.ts:736新代码应统一使用isLoadingisFetching任何一次queryFn执行期间都为true包括首次加载与后台刷新isRefetching仅后台刷新时为true等价于isFetching !isPendingisPlaceholderData当前展示的是placeholderData例如为获得平滑分页体验而提供的占位数据dataUpdatedAt/errorUpdatedAt最近一次成功 / 失败的时间戳failureCount/failureReason连续失败次数与失败原因用于自定义重试策略。无限查询专属字段分页能力的类型契约CreateInfiniteQueryResult与普通CreateQueryResult的最大区别在于InfiniteQueryObserverBaseResultpackages/query-core/src/types.ts:904追加的六个分页相关成员字段类型语义fetchNextPage(options?: FetchNextPageOptions) PromiseInfiniteQueryObserverResultTData, TError请求下一页返回更新后的完整结果fetchPreviousPage(options?: FetchPreviousPageOptions) PromiseInfiniteQueryObserverResultTData, TError请求上一页hasNextPageboolean是否还有下一页依据getNextPageParam的返回值判断hasPreviousPageboolean是否还有上一页依据getPreviousPageParam的返回值判断isFetchNextPageErrorboolean下一页请求是否失败isFetchingNextPageboolean下一页请求是否正在进行isFetchPreviousPageErrorboolean上一页请求是否失败isFetchingPreviousPageboolean上一页请求是否正在进行其中fetchNextPage/fetchPreviousPage可选的cancelRefetch参数packages/query-core/src/types.ts:640默认值为true若为true在上一请求未完成时再次调用会取消旧请求并重新执行queryFn若为false则重复调用在旧请求完成前不产生任何效果。值得注意的细节是分页错误标志isFetchNextPageError等与查询级错误是正交的加载更多失败并不会把status从success改为error已展示的页面数据会完整保留这正是无限滚动场景下加载更多失败但列表仍可用交互模式的类型基础。实战应用判别联合驱动的分页 UI场景一Load More 按钮来自createInfiniteQuery的 JSDoc 示例packages/svelte-query/src/createInfiniteQuery.ts:69展示了最经典的分页用法其中query的类型即为CreateInfiniteQueryResultscript langts import { createInfiniteQuery } from tanstack/svelte-query const query createInfiniteQuery(() ({ queryKey: [projects], queryFn: ({ pageParam }) fetchProjects(pageParam), initialPageParam: 0, getNextPageParam: (lastPage) lastPage.nextId, })) /script {#if query.isPending} Loading... {:else if query.isError} spanError: {query.error.message}/span {:else} ul {#each query.data.pages as page} {#each page.projects as project (project.id)} li{project.name}/li {/each} {/each} /ul button onclick{() query.fetchNextPage()} disabled{!query.hasNextPage || query.isFetching} {query.isFetchingNextPage ? Loading more... : query.hasNextPage ? Load More : Nothing more to load} /button {/if}在这段代码中判别联合在{#if}分支中发挥了关键作用isPending分支里data类型为undefined而{:else}分支里data被收窄为InfiniteDataTQueryFnData因此query.data.pages的嵌套遍历完全类型安全query.error.message也只在isError分支中被访问。场景二滚动自动加载同一个源码文件中的第二个示例packages/svelte-query/src/createInfiniteQuery.ts:108演示了基于IntersectionObserver的无限滚动同样建立在CreateInfiniteQueryResult的字段语义之上script langts import { createInfiniteQuery } from tanstack/svelte-query const query createInfiniteQuery(() ({ queryKey: [projects], queryFn: ({ pageParam }) fetchProjects(pageParam), initialPageParam: 0, getNextPageParam: (lastPage) lastPage.nextId, })) let sentinel: HTMLDivElement | undefined $state() $effect(() { if (sentinel null || !query.hasNextPage || query.isFetching) return const observer new IntersectionObserver(([entry]) { if (entry?.isIntersecting) query.fetchNextPage() }) observer.observe(sentinel) return () observer.disconnect() }) /script {#if query.isPending} Loading... {:else if query.isError} spanError: {query.error.message}/span {:else} ul {#each query.data.pages as page} {#each page.projects as project (project.id)} li{project.name}/li {/each} {/each} /ul div bind:this{sentinel}/div {/if}hasNextPage与isFetching的组合保证了哨兵元素只在还有下一页且当前没有请求进行中时才触发监听避免重复请求fetchNextPage()返回的PromiseInfiniteQueryObserverResult...也可以用于加载完成后的滚动位置修正等后续处理。与 DefinedCreateInfiniteQueryResult 的区别initialData 的类型分叉createInfiniteQuery根据是否传入initialData返回两种不同的结果类型这一分叉由函数重载实现packages/svelte-query/src/createInfiniteQuery.ts:21 与 packages/svelte-query/src/createInfiniteQuery.ts:40传入DefinedInitialDataInfiniteOptions即设置了initialData时返回DefinedCreateInfiniteQueryResultTData, TError传入UndefinedInitialDataInfiniteOptions时返回CreateInfiniteQueryResultTData, TError。对应的类型别名定义在 packages/svelte-query/src/types.ts:75/** Result from createInfiniteQuery with initialData */ export type DefinedCreateInfiniteQueryResult TData unknown, TError DefaultError, DefinedInfiniteQueryObserverResultTData, TError而DefinedInfiniteQueryObserverResultpackages/query-core/src/types.ts:1051只包含RefetchError与Success两个成员剔除了所有data: undefined的状态。也就是说一旦你提供了initialDataTypeScript 会在类型层面保证query.data始终非空即使在错误与加载分支中UI 无需再对数据是否存在做防御性判断——这是 TanStack Query 类型系统最实用的设计之一也是两个结果类型在实践中最需要区分的地方。总结CreateInfiniteQueryResult虽然只是 packages/svelte-query/src/types.ts:68 中的一行类型别名但它承载的是 query-core 完整的无限查询状态机以status为判别键的五成员联合类型覆盖了从首次加载、加载失败、刷新失败到成功、占位数据的全部生命周期fetchNextPage、hasNextPage、isFetchingNextPage等专属字段把分页控制封装为类型安全的 APIinitialData分支则通过DefinedCreateInfiniteQueryResult在编译期就消除了空数据访问的隐患。理解这层类型契约是在 Svelte 中写出健壮、可维护的无限滚动与分页应用的前提。如需进一步探索可继续阅读同目录下的 DefinedCreateInfiniteQueryResult、CreateInfiniteQueryOptions 与 createInfiniteQuery 的完整文档并在 packages/svelte-query/src/createInfiniteQuery.ts 与 packages/query-core/src/types.ts 中查看全部源码实现。【免费下载链接】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),仅供参考
返回列表