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

Typescript error when compiling a module using apollo-client and apollo-cache-inmemory #2503

Closed
bkon opened this issue Nov 7, 2017 · 22 comments

Comments

@bkon
Copy link

bkon commented Nov 7, 2017

Intended outcome:

Successful compilation of the project.

Actual outcome:

ERROR in [at-loader] ./node_modules/apollo-cache-inmemory/lib/inMemoryCache.d.ts:5:22
    TS2415: Class 'InMemoryCache' incorrectly extends base class 'ApolloCache<NormalizedCacheObject>'.
  Types of property 'read' are incompatible.
    Type '<T>(query: ReadOptions) => T | null' is not assignable to type '<T>(query: ReadOptions) => T'.
      Type 'T | null' is not assignable to type 'T'.
        Type 'null' is not assignable to type 'T'.

How to reproduce the issue:
tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "jsx": "preserve",
    "target": "es2015",
    "lib": ["es2017", "dom", "esnext.asynciterable"],
    "module": "es2015",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "strictNullChecks": true,
    "allowSyntheticDefaultImports": false,
    "baseUrl": ".",
    "paths": {
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Sample module:

import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient, ApolloQueryResult } from "apollo-client";
import { HttpLink } from "apollo-link-http";
import gql from "graphql-tag";

const client = new ApolloClient({
  cache: new InMemoryCache() as any,
  link: new HttpLink({ uri: process.env.GRAPHQL_ENDPOINT })
});

Version

** Possible cause **

apollo-cache defines ApolloCache base class with read method which cannot miss:

abstract read<T>(query: Cache.ReadOptions): T

apollo-cache-inmemory actually has more realistic definition of the return value as T | null

@tackley
Copy link

tackley commented Nov 7, 2017

Temporary, and unfortunate, workaround is to set "strictNullChecks": false 😞

@rhodee
Copy link

rhodee commented Nov 7, 2017

@tackley thank you for the suggestion.

After following the suggestion to set strictNullChecks to false. I experience another TypeError:

'Type 'ApolloClient<NormalizedCacheObject>' is not assignable to type 'ApolloClient<Cache>'

Below is the client/server code for rendering resulting in the error. The ApolloClient is created as stated in the docs.

// server.js
export const rootRoute = (req: express.Request, res: express.Response) => {
  const location = req.url
  const context: AppContext = {}
  const client = createApolloServer() // Create ApolloClient
  const store: Redux.Store<Store> = configureStore()

  const rawHTML = (
    <ApolloProvider client={client}> <----ERROR FROM ABOVE HERE
      <Provider store={store}> <---- Redux store
        <StaticRouter location={location} context={context}>
          <Main />
        </StaticRouter>
      </Provider>
    </ApolloProvider>
  )
}
// client.js
  const client = createApolloBrowser()
  const history = createHistory()
  const store: Redux.Store<Store> = configureStore()

  hydrate(
    <ApolloProvider client={client}> <----ERROR FROM ABOVE HERE
      <Provider store={store}> <---- Redux store
        <ConnectedRouter history={history}>
          <Main />
        </ConnectedRouter>
      </Provider>
    </ApolloProvider>,
    rootNode
  )

Below are the current set of dependencies:

    "apollo-cache-inmemory": "^1.1.0",
    "apollo-client-preset": "^1.0.2",
    "apollo-client": "^2.0.2",
    "apollo-link-context": "^1.0.0",
    "apollo-link-http": "^1.1.0",
    "react-apollo": "^2.0.0"

Thank you team Apollo for all your effort!

@donaldpipowitch
Copy link

For now you can also set skipLibCheck to true. Might be better for this issue.

@rhodee
Copy link

rhodee commented Nov 7, 2017

@donaldpipowitch still seeing the error. Webpack emits

TS2322: Type '{ client: ApolloClient<NormalizedCacheObject>; children: Element; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<ApolloProvider> & Readonly<{ children?: ReactNode;...'.
  Type '{ client: ApolloClient<NormalizedCacheObject>; children: Element; }' is not assignable to type 'Readonly<ProviderProps<Cache>>'.
    Types of property 'client' are incompatible.
      Type 'ApolloClient<NormalizedCacheObject>' is not assignable to type 'ApolloClient<Cache>'.
        Type 'NormalizedCacheObject' is not assignable to type 'Cache'.
          Property 'add' is missing in type 'NormalizedCacheObject'.

@Wenzil
Copy link

Wenzil commented Nov 7, 2017

Yeah, same error here

@Wenzil
Copy link

Wenzil commented Nov 7, 2017

The issue seems to be that the Cache type parameter isn't declared anywhere in react-apollo's type definitions

@mikberg
Copy link

mikberg commented Nov 9, 2017

This seems to work together with skipLibCheck: true.

import { ApolloCache } from 'apollo-cache';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';

const client = new ApolloClient({
  cache: new InMemoryCache() as ApolloCache<NormalizedCacheObject>,
  link: new HttpLink({ uri: '/graphql' }),
});

// ... later ...

<ApolloProvider client={client as ApolloClient<any>}>
  {/* ... */}
</ApolloProvider>

@corydeppen
Copy link

While the return type of the read method in the base class is still an issue, I think the issue related to ApolloProvider should be resolved by apollographql/react-apollo#1299.

@jbaxleyiii jbaxleyiii added this to the Post 2.0 bugs milestone Nov 13, 2017
@jbaxleyiii
Copy link
Contributor

Does anyone have an example TS project I can use to test changes and fix this?

@AlexanderEkdahl
Copy link

@jbaxleyiii Here's a minimal repository reproducing this bug: https://github.com/AlexanderEkdahl/apollo-client-typescript-bug

@AlexanderEkdahl
Copy link

@jbaxleyiii I'm afraid this did not fix the issue.

If you clone my repository and then run yarn upgrade followed by ./node_modules/.bin/tsc the issue persists. The fix is to modify the base class to allow null being returned from the read query. The client expects a type conforming to the base class which the InMemoryCache class does not.

@amitport
Copy link

@jbaxleyiii please re-open, just installed everything in a new project ([email protected]). I'm still getting this error.

@prencher
Copy link

This still happens: https://gist.github.com/prencher/ad626ca0ec21ce8bfc41e4bfcfc54a81

Turning strictNullChecks off is not an answer to this problem. What can we do to get this actually resolved?

@prencher
Copy link

prencher commented Nov 28, 2017

@jbaxleyiii It seems like you merged what may be a fix just after the most recent release - assuming that's correct, can we get a patch release, or at least a beta/rc with the fix?

@theadactyl
Copy link
Contributor

@prencher we'll follow up on this ASAP - thanks for your patience!

@mbrochh
Copy link

mbrochh commented Jan 16, 2019

Am I right to assume that this is still not fixed? I have this code:

    const client = new ApolloClient({
      cache: new InMemoryCache(),
      link: batchHttpLink,
      queryDeduplication: true,
      ssrMode: true,
    })

and am getting this TS error:

Type 'InMemoryCache' is not assignable to type 'ApolloCache<NormalizedCacheObject>'.
  Property 'data' is protected in type 'InMemoryCache' but public in type 'ApolloCache<NormalizedCacheObject>'. [2322]

@leocavalcante
Copy link

@mbrochh
The trick (?) is to use the interface NormalizedCacheObject as the generic type for TCacheShape:

new ApolloClient<NormalizedCacheObject>({
    ssrMode: typeof window === 'undefined',
    link: auth.concat(http),
    cache: new InMemoryCache(),
});

@pbn04001
Copy link

pbn04001 commented Feb 19, 2020

This is still an issue.

"apollo-boost": "^0.4.7",
    "react-apollo": "^3.1.3",

My code

import React from 'react'
import ReactDOM from 'react-dom'
import { withApollo, ApolloProvider } from 'react-apollo'
import { ApolloClient, ApolloLink, InMemoryCache, HttpLink, NormalizedCacheObject } from 'apollo-boost'

const httpLink = new HttpLink({ uri: url })

const authLink = new ApolloLink((operation, forward) => {
  // Call the next link in the middleware chain.
  return forward(operation)
})

const client = new ApolloClient<NormalizedCacheObject>({
  link: authLink.concat(httpLink), // Chain it with the HttpLink
  cache: new InMemoryCache() as any
})

const AppWithApollo = withApollo(App)

const Index = () => (
  <ApolloProvider client={client as ApolloClient<any>}>
    <AppWithApollo />
  </ApolloProvider>
)

ERROR in /Users/Peter/Workspace/petenelson.dev/src/index.tsx
./src/index.tsx
[tsl] ERROR in /Users/Peter/Workspace/petenelson.dev/src/index.tsx(23,46)
TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type '{ client: ApolloClient; }' is not assignable to parameter of type 'Attributes & ApolloProviderProps'.
Property 'children' is missing in type '{ client: ApolloClient; }' but required in type 'ApolloProviderProps'.

@hugomn
Copy link

hugomn commented May 24, 2020

For those looking for a great example of next with apollo and typescript, here's the repo that saved me: https://github.com/borisowsky/next-advanced-starter

@ryanberckmans
Copy link

This compiles in TypeScript for me

import { ApolloClient } from 'apollo-client';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

export function createApolloClient(): ApolloClient<NormalizedCacheObject> {
  return new ApolloClient({
    link: new HttpLink({
      uri: "...",
    }),
    cache: new InMemoryCache(),
  });
}

@nboukeffa
Copy link

I fixed it by removing apollo-boost dependency.

@ruben-montes
Copy link

This works for me:

import { useApolloClient, ApolloClient } from 'apollo-client';

export function getApolloClientInstance(): ApolloClient<object> {
  return useApolloClient();
}

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests