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

Cannot pass an optional infiniteData parameter to infiniteQueryOptions function #8132

Closed
jimmycallin opened this issue Oct 4, 2024 · 5 comments · Fixed by #8154
Closed
Labels
bug Something isn't working infinite queries types

Comments

@jimmycallin
Copy link
Contributor

jimmycallin commented Oct 4, 2024

Describe the bug

It doesn't seem possible to pass an optional initialData parameter to infiniteQueryOptions, while it does work for useInfiniteQuery.

Example query not working:

See playground example here.

Your minimal, reproducible example

https://www.typescriptlang.org/play/?ssl=18&ssc=1&pln=19&pc=1#code/JYWwDg9gTgLgBAbzgVwM4FMCSA7AZsbYGdARWXSgE84BfOXKCEOAIgAEYBDbVLgYwDWAeijpOfGAFoAjuSosA3ACgluZNgnAI2FBgDqUTmDAUAFEgJFgnADYARTl1oAuRHEsxr9x5wD8rpHQAD05wG3RXGChyWloASkQlODg+bV44WQpKAHkwTzS4AF53PA9SORy8rR5zJOSMioBpdEpXAG0WYNCwcJYAXQAaOuTMqgAxbFdOVEoNOFMEwoA+EqtbBy4h+tXPdZ9XDy8NzmH633nFlfM4ME4Ac3RUdsO9rkGb+-QABU5DECe4G0+vFTslXOoACbofDYdAQrb1B4wABywRgPwePz+rgWRRWAEYEckXjYMd9fqFXIS6jQ4soaCo1Bp8jo0OgDEYTFAyFlriTji43PyfP43F0whE4FEYnRaYlkqIYMgoKyMDgYURyryEKdRpRmq1AZ0QhL+kSGlkJlMZnNccsdkcfObhVwDoRdt4uKC4Oc7VckLcHgC2i7OO9A+S-sHgbTveDsFCYXDzUjUUF0Z8sZSLni4NTtiSyVmQFSEbT6UA

Steps to reproduce

function useWrapper({ initialData }: { initialData?: { example: true } }) {
  const queryOptions = infiniteQueryOptions({
    queryKey: ["example"],
    queryFn: async () => initialData,
   // initialData below errors
    initialData: initialData
      ? () => ({ pages: [initialData], pageParams: [] })
      : undefined,
    getNextPageParam: () => 1,
    initialPageParam: 1,
  });
}

Typescript error:

No overload matches this call.
  Overload 1 of 2, '(options: DefinedInitialDataInfiniteOptions<{ example: true; } | undefined, Error, InfiniteData<{ example: true; } | undefined, unknown>, string[], number>): UseInfiniteQueryOptions<...> & ... 1 more ... & { ...; }', gave the following error.
    Type '(() => { pages: { example: true; }[]; pageParams: never[]; }) | undefined' is not assignable to type '(InfiniteData<{ example: true; } | undefined, number> | InitialDataFunction<InfiniteData<{ example: true; } | undefined, number>> | undefined) & (InfiniteData<...> | (() => InfiniteData<...>))'.
      Type 'undefined' is not assignable to type '(InfiniteData<{ example: true; } | undefined, number> | InitialDataFunction<InfiniteData<{ example: true; } | undefined, number>> | undefined) & (InfiniteData<...> | (() => InfiniteData<...>))'.
  Overload 2 of 2, '(options: UndefinedInitialDataInfiniteOptions<{ example: true; } | undefined, Error, InfiniteData<{ example: true; } | undefined, unknown>, string[], number>): UseInfiniteQueryOptions<...> & ... 1 more ... & { ...; }', gave the following error.
    Type '(() => { pages: { example: true; }[]; pageParams: never[]; }) | undefined' is not assignable to type 'undefined'.
      Type '() => { pages: { example: true; }[]; pageParams: never[]; }' is not assignable to type 'undefined'.(2769)

Expected behavior

Equivalent example using useInfiniteQuery that works fine:

function useWrapperQuery({ initialData }: { initialData?: { example: true } }) {
  return useInfiniteQuery({
    queryKey: ["example"],
    queryFn: async () => initialData,
    initialData: initialData
      ? () => ({ pages: [initialData], pageParams: [] })
      : undefined,
    getNextPageParam: () => 1,
    initialPageParam: 1,
  });
}

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

N/A

Tanstack Query adapter

react-query

TanStack Query version

v5.59.0

TypeScript version

v5.6.2

Additional context

No response

@ddoemonn
Copy link

ddoemonn commented Oct 6, 2024

@jimmycallin You have to use initialPageParam like this:

function useWrapperQuery() {
  const options = infiniteQueryOptions({
    initialPageParam: 1,
    queryKey: ["users"],
    queryFn: async ({ pageParam = 1 }) => {
      const response = await fetch(`https://randomuser.me/api/?page=${pageParam}&results=10`);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    },
    getNextPageParam: (lastPage, allPages) => {
      const nextPage = allPages.length + 1;
      return nextPage <= 100 ? nextPage : undefined;
    },
  });

  return useInfiniteQuery(options);
}

@jimmycallin
Copy link
Contributor Author

@jimmycallin You have to use initialPageParam like this:

function useWrapperQuery() {
const options = infiniteQueryOptions({
initialPageParam: 1,
queryKey: ["users"],
queryFn: async ({ pageParam = 1 }) => {
const response = await fetch(https://randomuser.me/api/?page=${pageParam}&results=10);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
},
getNextPageParam: (lastPage, allPages) => {
const nextPage = allPages.length + 1;
return nextPage <= 100 ? nextPage : undefined;
},
});

return useInfiniteQuery(options);
}

I don't quite understand how this helps - what does this have to do with the issue I have with initialData?

@TkDodo TkDodo added bug Something isn't working types infinite queries labels Oct 7, 2024
@sungpaks
Copy link
Contributor

sungpaks commented Oct 9, 2024

It seems that this error occurs because the type of infiniteQueryOptions is actually devided in two types, DefinedInitialDataInfiniteOptions and UndefinedInitialDataInfiniteOptions.
So, TypeScript now tries to guarantee the type by using one or the other, but neither of them allow initialData | undefined, so we get this error.
🤔 I still wonder why infiniteQueryOptions type had to be like this.

Anyway, to silence this error temporarily, you can do like :

const queryOptions = initialData ? infiniteQueryOptions({
    queryKey: ["example"],
    queryFn: async () => initialData,
    initialData: () => ({ pages: [initialData], pageParams: [] }),
    getNextPageParam: () => 1,
    initialPageParam: 1,
  }) : infiniteQueryOptions({
    queryKey: ["example"],
    queryFn: async () => initialData,
    initialData: undefined,
    getNextPageParam: () => 1,
    initialPageParam: 1,
  })

It does fatten up the code unnecessarily, but.. this is one of the way.

@TkDodo
Copy link
Collaborator

TkDodo commented Oct 9, 2024

but neither of them allow initialData | undefined

UndefinedInitialDataInfiniteOptions definitely should allow it. Compare with the types for queryOptions

@sungpaks
Copy link
Contributor

sungpaks commented Oct 9, 2024

I fixed definedInitialQueryOptions to allow and opened a PR.
I'll modify it again to allow unDefinedInitialQueryOptions, based on what you've told, is that okay?

The above is reflected in the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working infinite queries types
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants