Skip to content

UseQueryOptions<TQueryFnData, TError> Defaults & Type Error #2795

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

Closed
blanchak opened this issue Oct 14, 2021 · 2 comments
Closed

UseQueryOptions<TQueryFnData, TError> Defaults & Type Error #2795

blanchak opened this issue Oct 14, 2021 · 2 comments
Labels
duplicate This issue or pull request already exists

Comments

@blanchak
Copy link

Describe the bug

Up to version v3.24.6 I was able to define our type for UseQueryOptions by only specifying the two first generics. As of version v3.25.0 I get a Typescript error because the underlying types no longer match even though the UseQueryOptions signature hasn't changed.

I suspect TS is getting hung up on the fact that refetchInterval now is able to accept a function.

Please advise.

To Reproduce

export interface SampleResponse {
  data: { id: number }[];
}

export const useBugSample = (queryOptions?: UseQueryOptions<SampleResponse, HttpClientResponseError>): UseQueryResult<SampleResponse, HttpClientResponseError> => {
  return useQuery(['SampleQueryKey'], fetchSample, {
    cacheTime: Infinity,
    staleTime: Infinity,
    ...queryOptions,
  });
};

export const fetchSample = async (): Promise<SampleResponse> => {
  return { data: [{ id: 1 }, { id: 2 }] };
};

Expected behavior

Screenshots
image

Desktop (please complete the following information):

  • OS: Windows 10 (10.0.19042 Build 19042)
  • Browser: Chrome
  • Version: 94.0.4606.81

Additional context

Argument of type '{ enabled?: boolean | undefined; staleTime: number; refetchInterval?: number | false | ((data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, QueryKey>) => number | false) | undefined; ... 30 more ...; _defaulted?: boolean | undefined; }' is not assignable to parameter of type 'Omit<UseQueryOptions<SampleResponse, HttpClientResponseError, SampleResponse, string[]>, "queryKey" | "queryFn">'.
  Types of property 'refetchInterval' are incompatible.
    Type 'number | false | ((data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, QueryKey>) => number | false) | undefined' is not assignable to type 'number | false | ((data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, string[]>) => number | false) | undefined'.
      Type '(data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, QueryKey>) => number | false' is not assignable to type 'number | false | ((data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, string[]>) => number | false) | undefined'.
        Type '(data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, QueryKey>) => number | false' is not assignable to type '(data: SampleResponse | undefined, query: Query<SampleResponse, HttpClientResponseError, SampleResponse, string[]>) => number | false'.
          Types of parameters 'query' and 'query' are incompatible.
            Type 'Query<SampleResponse, HttpClientResponseError, SampleResponse, string[]>' is not assignable to type 'Query<SampleResponse, HttpClientResponseError, SampleResponse, QueryKey>'.
              The types of 'options.queryFn' are incompatible between these types.
                Type 'QueryFunction<SampleResponse, string[]> | undefined' is not assignable to type 'QueryFunction<SampleResponse, QueryKey> | undefined'.
                  Type 'QueryFunction<SampleResponse, string[]>' is not assignable to type 'QueryFunction<SampleResponse, QueryKey>'.
                    Type 'QueryKey' is not assignable to type 'string[]'.
                      Type 'string' is not assignable to type 'string[]'.ts(2345)

Dependencies

"dependencies": {
    "@emotion/cache": "^11.4.0",
    "@emotion/react": "^11.4.1",
    "@emotion/server": "^11.4.0",
    "@emotion/styled": "^11.3.0",
    "@microsoft/applicationinsights-web": "^2.7.0",
    "@mui/icons-material": "^5.0.3",
    "@mui/lab": "^5.0.0-alpha.50",
    "@mui/material": "^5.0.3",
    "@mui/styles": "^5.0.1",
    "applicationinsights": "^2.1.8",
    "content-security-policy-builder": "^2.1.0",
    "markdown-to-jsx": "^7.1.3",
    "next": "^11.1.2",
    "next-seo": "^4.28.1",
    "next-translate": "^1.1.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-query": "3.25.0",
    "sharp": "^0.29.1",
    "timeago.js": "^4.0.2"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^12.1.2",
    "@types/jest-axe": "^3.5.3",
    "@types/node": "^16.10.5",
    "@types/preval.macro": "^3.0.0",
    "@types/react": "^17.0.29",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "babel-plugin-macros": "^3.1.0",
    "cross-env": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-config-next": "^11.1.2",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-header": "^3.1.1",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "jest": "^27.2.5",
    "jest-axe": "^5.0.1",
    "jest-junit": "^13.0.0",
    "jest-sonar-reporter": "^2.0.0",
    "msw": "^0.35.0",
    "prettier": "^2.4.1",
    "preval.macro": "^5.0.0",
    "typescript": "^4.4.4"
  },

@TkDodo
Copy link
Collaborator

TkDodo commented Oct 14, 2021

please see: #2753 (comment)

@TkDodo TkDodo closed this as completed Oct 14, 2021
@TkDodo TkDodo added the duplicate This issue or pull request already exists label Oct 14, 2021
@TkDodo
Copy link
Collaborator

TkDodo commented Oct 14, 2021

Additionally, I think you could solve it by "up-casting" your query, e.g. by doing:

  • ['SampleQueryKey'] as QueryKey
  • or by passing the same generics to useQuery, e.g. instead of using UseQueryResult:
export const useBugSample = (queryOptions?: UseQueryOptions<SampleResponse, HttpClientResponseError>) => {
  return useQuery<SampleResponse, HttpClientResponseError>(['SampleQueryKey'], fetchSample, {
    cacheTime: Infinity,
    staleTime: Infinity,
    ...queryOptions,
  });
};

but those approaches have all the flaws as outlined in the other comment: select won't work, and consumers of that custom hook can still override queryKeys and queryFn. If that's okay for your use-case, this is a good alternative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants