diff --git a/packages/solid-query/src/__tests__/createInfiniteQuery.test-d.tsx b/packages/solid-query/src/__tests__/createInfiniteQuery.test-d.tsx new file mode 100644 index 0000000000..eea81df7c1 --- /dev/null +++ b/packages/solid-query/src/__tests__/createInfiniteQuery.test-d.tsx @@ -0,0 +1,109 @@ +import { describe } from 'node:test' +import { expectTypeOf, it } from 'vitest' +import { type InfiniteData, dataTagSymbol } from '@tanstack/query-core' +import { + createInfiniteQuery, + infiniteQueryOptions, +} from '../createInfiniteQuery' +import type { + DefinedInitialDataInfiniteOptions, + UndefinedInitialDataInfiniteOptions, +} from '../createInfiniteQuery' + +const doNotRun = (_callback: () => void) => {} + +describe('infiniteQueryOptions', () => { + it('should infer defined types', () => { + const options = infiniteQueryOptions({ + getNextPageParam: () => 10, + queryKey: ['key'], + queryFn: () => ({ wow: true }), + initialData: { + pageParams: [undefined], + pages: [{ wow: true }], + }, + initialPageParam: 0, + }) + + doNotRun(() => { + expectTypeOf< + InfiniteData< + { + wow: boolean + }, + unknown + > + >(createInfiniteQuery(() => options).data) + + expectTypeOf< + ReturnType< + DefinedInitialDataInfiniteOptions< + { + wow: boolean + }, + Error, + InfiniteData< + { + wow: boolean + }, + unknown + >, + Array, + number | undefined + > + > + >(options) + + expectTypeOf(options.queryKey[dataTagSymbol]).toEqualTypeOf< + InfiniteData<{ wow: boolean }> + >() + }) + }) + + it('should work without defined types', () => { + const options = infiniteQueryOptions({ + getNextPageParam: () => undefined, + queryKey: ['key'], + queryFn: () => ({ wow: true }), + initialPageParam: 0, + }) + + doNotRun(() => { + expectTypeOf< + () => + | InfiniteData< + { + wow: boolean + }, + unknown + > + | undefined + >(() => createInfiniteQuery(() => options).data) + + expectTypeOf< + ReturnType< + UndefinedInitialDataInfiniteOptions< + { + wow: boolean + }, + Error, + InfiniteData< + { + wow: boolean + }, + unknown + >, + Array, + number + > + > + >(options) + + expectTypeOf(options.queryKey[dataTagSymbol]).toEqualTypeOf< + InfiniteData<{ + wow: boolean + }> + >() + }) + }) +}) diff --git a/packages/solid-query/src/__tests__/createInfiniteQuery.test.tsx b/packages/solid-query/src/__tests__/createInfiniteQuery.test.tsx index 1e174fe81b..e41253fb13 100644 --- a/packages/solid-query/src/__tests__/createInfiniteQuery.test.tsx +++ b/packages/solid-query/src/__tests__/createInfiniteQuery.test.tsx @@ -15,6 +15,7 @@ import { QueryCache, QueryClientProvider, createInfiniteQuery, + infiniteQueryOptions, keepPreviousData, } from '..' import { @@ -2056,4 +2057,30 @@ describe('useInfiniteQuery', () => { await waitFor(() => rendered.getByText('Status: custom client')) }) + + it('should work with infiniteQueryOptions', async () => { + const key = queryKey() + const options = infiniteQueryOptions({ + getNextPageParam: () => undefined, + queryKey: key, + initialPageParam: 0, + queryFn: () => Promise.resolve(220), + }) + + function Page() { + const state = createInfiniteQuery( + () => options, + () => queryClient, + ) + return ( +
+

Status: {state.data?.pages[0]}

+
+ ) + } + + const rendered = render(() => ) + + await waitFor(() => rendered.getByText('Status: 220')) + }) }) diff --git a/packages/solid-query/src/createInfiniteQuery.ts b/packages/solid-query/src/createInfiniteQuery.ts index ec79c76b0e..10e08b96ac 100644 --- a/packages/solid-query/src/createInfiniteQuery.ts +++ b/packages/solid-query/src/createInfiniteQuery.ts @@ -2,6 +2,7 @@ import { InfiniteQueryObserver } from '@tanstack/query-core' import { createMemo } from 'solid-js' import { createBaseQuery } from './createBaseQuery' import type { + DataTag, DefaultError, InfiniteData, QueryKey, @@ -11,9 +12,146 @@ import type { QueryClient } from './QueryClient' import type { CreateInfiniteQueryOptions, CreateInfiniteQueryResult, + DefinedCreateInfiniteQueryResult, + FunctionedParams, + SolidInfiniteQueryOptions, } from './types' import type { Accessor } from 'solid-js' +export type UndefinedInitialDataInfiniteOptions< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> = FunctionedParams< + SolidInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey, + TPageParam + > & { + initialData?: undefined + } +> +type NonUndefinedGuard = T extends undefined ? never : T +export type DefinedInitialDataInfiniteOptions< + TQueryFnData, + TError = DefaultError, + // should we handle page param correctly + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +> = FunctionedParams< + SolidInfiniteQueryOptions< + TQueryFnData, + TError, + TData, + TQueryFnData, + TQueryKey, + TPageParam + > & { + initialData: + | NonUndefinedGuard> + | (() => NonUndefinedGuard>) + } +> +function infiniteQueryOptions< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +>( + options: ReturnType< + DefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + > + >, +): ReturnType< + DefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + > +> & { + queryKey: DataTag> +} +function infiniteQueryOptions< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +>( + options: ReturnType< + UndefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + > + >, +): ReturnType< + UndefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + > +> & { + queryKey: DataTag> +} + +function infiniteQueryOptions(options: unknown) { + return options +} + +export { infiniteQueryOptions } + +export function createInfiniteQuery< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +>( + options: DefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + queryClient?: Accessor, +): DefinedCreateInfiniteQueryResult +export function createInfiniteQuery< + TQueryFnData, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, + TPageParam = unknown, +>( + options: UndefinedInitialDataInfiniteOptions< + TQueryFnData, + TError, + TData, + TQueryKey, + TPageParam + >, + queryClient?: Accessor, +): CreateInfiniteQueryResult + export function createInfiniteQuery< TQueryFnData, TError = DefaultError, diff --git a/packages/solid-query/src/index.ts b/packages/solid-query/src/index.ts index 9d894999bf..aa2b74dd09 100644 --- a/packages/solid-query/src/index.ts +++ b/packages/solid-query/src/index.ts @@ -20,7 +20,14 @@ export { } from './QueryClientProvider' export type { QueryClientProviderProps } from './QueryClientProvider' export { useIsFetching } from './useIsFetching' -export { createInfiniteQuery } from './createInfiniteQuery' +export { + createInfiniteQuery, + infiniteQueryOptions, +} from './createInfiniteQuery' +export type { + DefinedInitialDataInfiniteOptions, + UndefinedInitialDataInfiniteOptions, +} from './createInfiniteQuery' export { createMutation } from './createMutation' export { useIsMutating } from './useIsMutating' export { useMutationState } from './useMutationState' diff --git a/packages/solid-query/src/types.ts b/packages/solid-query/src/types.ts index 85d3ce4ecb..952185fc9c 100644 --- a/packages/solid-query/src/types.ts +++ b/packages/solid-query/src/types.ts @@ -2,6 +2,7 @@ import type { DefaultError, + DefinedInfiniteQueryObserverResult, DefinedQueryObserverResult, InfiniteQueryObserverResult, MutateFunction, @@ -142,6 +143,11 @@ export type CreateInfiniteQueryResult< TError = DefaultError, > = InfiniteQueryObserverResult +export type DefinedCreateInfiniteQueryResult< + TData = unknown, + TError = DefaultError, +> = DefinedInfiniteQueryObserverResult + /* --- Create Mutation Types --- */ export interface SolidMutationOptions< TData = unknown,