Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type error when using experimental_createPersister with a queryFn that has an argument #7842

Open
EliasWatson opened this issue Aug 2, 2024 · 1 comment
Labels

Comments

@EliasWatson
Copy link

Describe the bug

When using experimental_createPersister from @tanstack/query-persist-client-core, TypeScript throws a type error in queryOptions() when queryFn has an argument, but doesn't throw a type error if queryFn has no arguments. The type error goes away if we define the generic argument on queryOptions().

Your minimal, reproducible example

https://codesandbox.io/p/github/EliasWatson/tanstack-query-persist-bug-example/main?import=true

Steps to reproduce

  1. Write a function to create a QueryPersister using experimental_createPersister.
function createPersister<TData>(): QueryPersister<TData, any> {
  return experimental_createPersister({ storage: undefined });
}
  1. Create query options using the persister function with a queryFn that has no arguments. Notice that there are no TypeScript errors.
queryOptions({
  queryKey: ['good-query'],
  queryFn: () => 'test',
  persister: createPersister<string>(),
});
  1. Add an argument to the queryFn. Notice that TypeScript now throws an error.
queryOptions({
  queryKey: ['bad-query'],
  // Ignoring the unused variable error:
  // @ts-expect-error
  queryFn: (args) => 'test',
  persister: createPersister<string>(), // Type error here!
});
src/App.tsx:23:5 - error TS2769: No overload matches this call.
  Overload 1 of 2, '(options: DefinedInitialDataOptions<unknown, Error, unknown, string[]>): UseQueryOptions<unknown, Error, unknown, string[]> & { initialData: unknown; } & { ...; }', gave the following error.
    Types of parameters 'queryFn' and 'queryFn' are incompatible.
      Type 'unknown' is not assignable to type 'string | Promise<string>'.
  Overload 2 of 2, '(options: UndefinedInitialDataOptions<unknown, Error, unknown, string[]>): UseQueryOptions<unknown, Error, unknown, string[]> & { initialData?: InitialDataFunction<...> | undefined; } & { ...; }', gave the following error.
    Type '(queryFn: QueryFunction<string, any, never>, context: { queryKey: any; signal: AbortSignal; meta: Record<string, unknown> | undefined; pageParam?: unknown; direction?: unknown; }, query: Query<...>) => string | Promise<...>' is not assignable to type '(queryFn: QueryFunction<unknown, string[], never>, context: { queryKey: string[]; signal: AbortSignal; meta: Record<string, unknown> | undefined; pageParam?: unknown; direction?: unknown; }, query: Query<...>) => unknown'.

23     persister: createPersister<string>(),
       ~~~~~~~~~

  node_modules/@tanstack/query-core/build/modern/hydration-DtrabBHC.d.ts:577:5
    577     persister?: QueryPersister<NoInfer<TQueryFnData>, NoInfer<TQueryKey>, NoInfer<TPageParam>>;
            ~~~~~~~~~
    The expected type comes from property 'persister' which is declared here on type 'DefinedInitialDataOptions<unknown, Error, unknown, string[]>'
  node_modules/@tanstack/query-core/build/modern/hydration-DtrabBHC.d.ts:577:5
    577     persister?: QueryPersister<NoInfer<TQueryFnData>, NoInfer<TQueryKey>, NoInfer<TPageParam>>;
            ~~~~~~~~~
    The expected type comes from property 'persister' which is declared here on type 'UndefinedInitialDataOptions<unknown, Error, unknown, string[]>'
  1. Specify the generic argument on queryOptions. Notice that the TypeScript error goes away.
queryOptions<string>({
  queryKey: ['fixed-bad-query'],
  // Ignoring the unused variable error:
  // @ts-expect-error
  queryFn: (args) => 'test',
  persister: createPersister<string>(),
});

Expected behavior

I expect TypeScript to not throw a type error when queryFn has an argument, just like it does when queryFn doesn't have arguments. I also don't want to have to specify the generic type on queryOptions since TypeScript has no problem inferring it when queryFn has no arguments.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

  • OS: MacOS
  • Browser: Google Chrome
  • Version: 127.0.6533.89 (Official Build) (arm64)

Tanstack Query adapter

react-query

TanStack Query version

v5.51.18

TypeScript version

v5.2.2

Additional context

No response

@TkDodo
Copy link
Collaborator

TkDodo commented Aug 6, 2024

it works if you omit the return type declaration QueryPersister<TData, any>:

I think it's related to "Intra expression inference" maybe ? TypeScript does inference differently if function parameters are used. Could be related to:

You can see that if you hover queryOptions where it errors, it's actually inferred as queryOptions<unknown, Error, unknown, string[]>. So data is of type unknown instead of string, which I think is because it can't be inferred from the queryFn for "reasons" 🤷

@TkDodo TkDodo added the types label Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants