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

Suggestion: improve ergonomics of *InfiniteOptions types #8477

Open
OliverJAsh opened this issue Dec 25, 2024 · 0 comments
Open

Suggestion: improve ergonomics of *InfiniteOptions types #8477

OliverJAsh opened this issue Dec 25, 2024 · 0 comments

Comments

@OliverJAsh
Copy link

OliverJAsh commented Dec 25, 2024

Describe the bug

The docs suggest using infiniteQueryOptions to abstract infinite query options. For example:

import { infiniteQueryOptions } from '@tanstack/react-query';

export const queryOptions = infiniteQueryOptions({
  queryKey: ['foo'],
  queryFn: ({ pageParam }) => Promise.resolve({ foo: 'bar' }),
  initialPageParam: 1,
  getNextPageParam: (lastPage, allPages, lastPageParam) => lastPageParam + 1,
});

However, when using TypeScript's isolated declarations (isolatedDeclarations), all module exports must have type annotations. For this reason it would be preferable to use a type annotation rather than the infiniteQueryOptions type constructor.

The problem with this, however, is it's very verbose:

import type {
  DefaultError,
  InfiniteData,
  QueryKey,
  UnusedSkipTokenInfiniteOptions,
} from '@tanstack/react-query';

type MyResponse = {
  foo: string;
};

export const queryOptions: UnusedSkipTokenInfiniteOptions<
  MyResponse,
  DefaultError,
  InfiniteData<MyResponse, number>,
  QueryKey,
  number
> = {
  queryKey: ['foo'],
  queryFn: ({ pageParam }) => Promise.resolve({ foo: 'bar' }),
  initialPageParam: 1,
  getNextPageParam: (lastPage, allPages, lastPageParam) => lastPageParam + 1,
};

Except for the first and last type parameters provided to UnusedSkipTokenInfiniteOptions, all the others could theoretically just use the defaults. However, we're forced to provide them because we need to provide TPageParam (the last type parameter), otherwise it would default to unknown.

Given more TypeScript users will likely be looking to enable isolated declarations in the future and thus be required to add type annotations, I wonder if we could make these types more ergonomic.

One idea would be to move the position of the TPageParam type parameter in the *InfiniteOptions types, so we can benefit from defaults. For example, if it was moved from last to second position then the example above would look much better:

import type {
  DefaultError,
  InfiniteData,
  QueryKey,
  UnusedSkipTokenInfiniteOptions,
} from '@tanstack/react-query';

type MyResponse = {
  foo: string;
};

export const queryOptions: UnusedSkipTokenInfiniteOptions<
  MyResponse,
  number
> = {
  queryKey: ['foo'],
  queryFn: ({ pageParam }) => Promise.resolve({ foo: 'bar' }),
  initialPageParam: 1,
  getNextPageParam: (lastPage, allPages, lastPageParam) => lastPageParam + 1,
};
-type UnusedSkipTokenInfiniteOptions<TQueryFnData, TError = DefaultError, TData = InfiniteData<TQueryFnData>, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown> = OmitKeyof<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey, TPageParam>, 'queryFn'> & {
    queryFn?: Exclude<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey, TPageParam>['queryFn'], SkipToken | undefined>;
};
+type UnusedSkipTokenInfiniteOptions<TQueryFnData, TPageParam = unknown, TError = DefaultError, TData = InfiniteData<TQueryFnData, TPageParam>, TQueryKey extends QueryKey = QueryKey> = OmitKeyof<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey, TPageParam>, 'queryFn'> & {
    queryFn?: Exclude<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey, TPageParam>['queryFn'], SkipToken | undefined>;
};

Your minimal, reproducible example

N/A

Steps to reproduce

N/A

Expected behavior

N/A

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

N/A

Tanstack Query adapter

None

TanStack Query version

N/A

TypeScript version

No response

Additional context

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant