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

Allow "cache-and-network" fetch policy with useQuery again #165

Closed
wants to merge 2 commits into from

Conversation

lachenmayer
Copy link

In [email protected], the cache-and-network fetch policy has been removed from the FetchPolicy type, as documented here: https://github.com/apollographql/apollo-client/blob/master/CHANGELOG.md#apollo-client-260-1

This results in type errors in any project that tries to use the cache-and-network fetch policy with useQuery using [email protected] (currently the latest release). To be clear, this very simple (valid!) use-case now results in a type error:

const { data } = useQuery(gql`...`, {
  fetchPolicy: 'cache-and-network', // Type '"cache-and-network"' is not assignable to type '"cache-first" | "network-only" | "cache-only" | "no-cache" | "standby" | undefined'.
})

It also results in the following type errors in the project:

(7 type errors, click to expand...)
> [email protected] typings-check /Users/harry/node_modules/react-apollo-hooks
> tsc --noEmit

node_modules/react-testing-library/typings/index.d.ts:13:46 - error TS2344: Type 'typeof import("/Users/harry/node_modules/react-apollo-hooks/node_modules/dom-testing-library/typings/queries")' does not satisfy the constraint 'Queries'.
  Property 'findByLabelText' is incompatible with index signature.
    Type 'FindByText' is not assignable to type 'Query'.
      Type 'Promise<HTMLElement>' is not assignable to type 'HTMLElement | HTMLElement[] | null'.
        Type 'Promise<HTMLElement>' is missing the following properties from type 'HTMLElement[]': length, pop, push, concat, and 26 more.

13 export type RenderResult<Q extends Queries = typeof queries> = {
                                                ~~~~~~~~~~~~~~

node_modules/react-testing-library/typings/index.d.ts:28:52 - error TS2344: Type 'typeof import("/Users/harry/node_modules/react-apollo-hooks/node_modules/dom-testing-library/typings/queries")' does not satisfy the constraint 'Queries'.

28 export interface RenderOptions<Q extends Queries = typeof queries> {
                                                      ~~~~~~~~~~~~~~

src/__tests__/getMarkupFromTree-test.tsx:163:15 - error TS2322: Type '"cache-and-network"' is not assignable to type '"no-cache" | "cache-first" | "network-only" | "cache-only" | "standby" | undefined'.

163               fetchPolicy="cache-and-network"
                  ~~~~~~~~~~~

  node_modules/apollo-client/core/watchQueryOptions.d.ts:18:5
    18     fetchPolicy?: FetchPolicy;
           ~~~~~~~~~~~
    The expected type comes from property 'fetchPolicy' which is declared here on type 'IntrinsicAttributes & UserWrapperProps'

src/__tests__/getMarkupFromTree-test.tsx:180:15 - error TS2322: Type '"cache-and-network"' is not assignable to type '"no-cache" | "cache-first" | "network-only" | "cache-only" | "standby" | undefined'.

180               fetchPolicy="cache-and-network"
                  ~~~~~~~~~~~

  node_modules/apollo-client/core/watchQueryOptions.d.ts:18:5
    18     fetchPolicy?: FetchPolicy;
           ~~~~~~~~~~~
    The expected type comes from property 'fetchPolicy' which is declared here on type 'IntrinsicAttributes & UserWrapperProps'

src/__tests__/useQuery-test.tsx:512:9 - error TS2322: Type '"cache-and-network"' is not assignable to type '"no-cache" | "cache-first" | "network-only" | "cache-only" | "standby" | undefined'.

512         fetchPolicy="cache-and-network"
            ~~~~~~~~~~~

  node_modules/apollo-client/core/watchQueryOptions.d.ts:18:5
    18     fetchPolicy?: FetchPolicy;
           ~~~~~~~~~~~
    The expected type comes from property 'fetchPolicy' which is declared here on type 'IntrinsicAttributes & TasksWrapperProps'

src/__tests__/useQuery-test.tsx:531:7 - error TS2322: Type '"cache-and-network"' is not assignable to type '"no-cache" | "cache-first" | "network-only" | "cache-only" | "standby" | undefined'.

531       fetchPolicy="cache-and-network"
          ~~~~~~~~~~~

  node_modules/apollo-client/core/watchQueryOptions.d.ts:18:5
    18     fetchPolicy?: FetchPolicy;
           ~~~~~~~~~~~
    The expected type comes from property 'fetchPolicy' which is declared here on type 'IntrinsicAttributes & TasksWrapperProps'

src/useQuery.ts:95:7 - error TS2367: This condition will always return 'false' since the types '"no-cache" | "cache-first" | "cache-only" | "standby" | undefined' and '"cache-and-network"' have no overlap.

95       actualCachePolicy === 'cache-and-network')
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 7 errors.

This issue has actually been reported here: apollographql/apollo-client#4849

The fix is to simply change the QueryOptions type to WatchQueryOptions, as useQuery uses watchQuery (which allows the cache-and-network fetch policy), and not query (which doesn't).

This exact change is implemented in the commit 184a7b5 (check this diff to look at the actual code changes!)

As a separate commit, I also ran npm run format. I initially did this to ensure that I did not introduce new style errors, but I actually found style errors in unrelated files. I hope this is not too controversial to add, if not I can revert/rebase.

When running npm run check-typings, I now only get 2 type errors, none of which are related to the fetch policy, and actually seem completely unrelated to the project:

(2 type errors, unrelated to this change, click to expand...)
> [email protected] typings-check /Users/harry/node_modules/react-apollo-hooks
> tsc --noEmit

node_modules/react-testing-library/typings/index.d.ts:13:46 - error TS2344: Type 'typeof import("/Users/harry/node_modules/react-apollo-hooks/node_modules/dom-testing-library/typings/queries")' does not satisfy the constraint 'Queries'.
  Property 'findByLabelText' is incompatible with index signature.
    Type 'FindByText' is not assignable to type 'Query'.
      Type 'Promise<HTMLElement>' is not assignable to type 'HTMLElement | HTMLElement[] | null'.
        Type 'Promise<HTMLElement>' is missing the following properties from type 'HTMLElement[]': length, pop, push, concat, and 26 more.

13 export type RenderResult<Q extends Queries = typeof queries> = {
                                                ~~~~~~~~~~~~~~

node_modules/react-testing-library/typings/index.d.ts:28:52 - error TS2344: Type 'typeof import("/Users/harry/node_modules/react-apollo-hooks/node_modules/dom-testing-library/typings/queries")' does not satisfy the constraint 'Queries'.

28 export interface RenderOptions<Q extends Queries = typeof queries> {
                                                      ~~~~~~~~~~~~~~


Found 2 errors.

Anyway, hope this is useful for anyone who accidentally upgraded to [email protected] & broke their TypeScript projects! :)

@lachenmayer
Copy link
Author

lachenmayer commented May 24, 2019

Took a look at the CI results - I'm just realised that this repo has apollo-client@^2.4.7 as a dependency (accidentally used npm instead of yarn which obviously ignored the lock file... #jslife). Upgrading that dependency to [email protected] results in some other type errors that I don't really understand at first glance.

(type errors, click to expand)
$ tsc --noEmit
node_modules/apollo-client/core/QueryManager.d.ts:73:117 - error TS2707: Generic type 'FetchResult' requires between 0 and 2 type arguments.

73     observeQuery<T>(queryId: string, options: WatchQueryOptions, observer: Observer<ApolloQueryResult<T>>): Promise<FetchResult<T, Record<string, any>, Record<string, any>>>;
                                                                                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/useQuery.ts:134:5 - error TS2345: Argument of type '() => { data: undefined; error: undefined; loading: false; networkStatus: undefined; fetchMore: (fetchMoreOptions: FetchMoreQueryOptions<TVariables, string | number | symbol> & FetchMoreOptions<TData, TVariables>) => Promise<...>; refetch: (variables?: TVariables | undefined) => Promise<...>; startPolling: (pollInte...' is not assignable to parameter of type '() => QueryHookResult<TData, TVariables>'.
  Type '{ data: undefined; error: undefined; loading: false; networkStatus: undefined; fetchMore: (fetchMoreOptions: FetchMoreQueryOptions<TVariables, string | number | symbol> & FetchMoreOptions<TData, TVariables>) => Promise<...>; refetch: (variables?: TVariables | undefined) => Promise<...>; startPolling: (pollInterval: ...' is not assignable to type 'QueryHookResult<TData, TVariables>'.
    Type '{ data: undefined; error: undefined; loading: false; networkStatus: undefined; fetchMore: (fetchMoreOptions: FetchMoreQueryOptions<TVariables, string | number | symbol> & FetchMoreOptions<TData, TVariables>) => Promise<...>; refetch: (variables?: TVariables | undefined) => Promise<...>; startPolling: (pollInterval: ...' is not assignable to type 'QueryHookResult<TData, TVariables>'.
      Types of property 'updateQuery' are incompatible.
        Type '(mapFn: (previousQueryResult: TData, options: UpdateQueryOptions<{}>) => TData) => void' is not assignable to type '<TVars = TVariables>(mapFn: (previousQueryResult: TData, options: UpdateQueryOptions<TVars>) => TData) => void'.
          Types of parameters 'mapFn' and 'mapFn' are incompatible.
            Types of parameters 'options' and 'options' are incompatible.
              Type 'UpdateQueryOptions<{}>' is not assignable to type 'UpdateQueryOptions<TVars>'.
                Type '{}' is not assignable to type 'TVars'.

134     () => {
        ~~~~~~~

src/useSubscription.ts:82:23 - error TS2345: Argument of type '{ data: ExecutionResultDataDefault | undefined; error: undefined; loading: boolean; }' is not assignable to parameter of type 'SubscriptionHookResult<TData>'.
  Types of property 'data' are incompatible.
    Type 'ExecutionResultDataDefault | undefined' is not assignable to type 'TData | undefined'.
      Type 'ExecutionResultDataDefault' is not assignable to type 'TData'.

82             setResult(newResult);
                         ~~~~~~~~~

src/useSubscription.ts:86:17 - error TS2322: Type '{ data: ExecutionResultDataDefault | undefined; error: undefined; loading: boolean; }' is not assignable to type 'SubscriptionHookResult<TData>'.

86                 subscriptionData: newResult,
                   ~~~~~~~~~~~~~~~~

  src/useSubscription.ts:20:3
    20   subscriptionData: SubscriptionHookResult<TData>;
         ~~~~~~~~~~~~~~~~
    The expected type comes from property 'subscriptionData' which is declared here on type 'OnSubscriptionDataOptions<TData>'


Found 4 errors.

If someone has pointers how to resolve those, that'd be great - otherwise maybe a workaround for now could be just to set theapollo-client peerDependency from * to <2.6.0 or similar? (Perfect example of why peer dependencies suck a lot...)

Nice one, thank you :)

@sgoll
Copy link
Contributor

sgoll commented May 30, 2019

If someone has pointers how to resolve those, that'd be great - otherwise maybe a workaround for now could be just to set theapollo-client peerDependency from * to <2.6.0 or similar? (Perfect example of why peer dependencies suck a lot...)

When I opened PR #169 just now I took the easy way and upgraded to a recent TypeScript version. Seems like something else changed in apollo-client and this looks like the easiest fix.

@lachenmayer
Copy link
Author

Sounds good, thanks for taking a look! Guess this PR can be closed then? (cc #163)

@trojanowski
Copy link
Owner

Fixed in version 0.5.0.

@trojanowski trojanowski closed this Jul 9, 2019
@lachenmayer
Copy link
Author

Excellent, thanks a lot @trojanowski and @sgoll!

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

Successfully merging this pull request may close these issues.

4 participants