Using node-fetch with apollo-link-http

May 23, 2019

I’m building a Gatsby app that consumes data from a graphQL service with the help of apollo-client and TypeScript. Because Gatsby creates static assets at build time, I needed a data-fetching tool that would work on the client-side and the server-side. apollo-client recommends using node-fetch for the task.

When I installed node-fetch and tried it out, I got this TypeScript error:

error TS7016: Could not find a declaration file for module 'node-fetch'. '/Users/mae.capozzi/Desktop/Codes/project/packages/client/node_modules/node-fetch/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/node-fetch` if it exists or add a new declaration (.d.ts) file containing `declare module 'node-fetch';`

8 import fetch from 'node-fetch';

Naturally, I installed @types/node-fetch. Rather than solving my problem, it led me to another one:

error TS2345: Argument of type '{ uri: string | undefined; credentials: string; fetch: typeof fetch; }' is not assignable to parameter of type 'Options'.
  Types of property 'fetch' are incompatible.
    Type 'typeof fetch' is not assignable to type '{ (input: RequestInfo, init?: RequestInit | undefined): Promise<Response>; (input: RequestInfo, init?: RequestInit | undefined): Promise<Response>; }'.
      Types of parameters 'url' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'import("/Users/mae.capozzi/Desktop/Codes/project/node_modules/@types/node-fetch/index").RequestInfo'.
          Type 'Request' is not assignable to type 'RequestInfo'.
            Type 'Request' is missing the following properties from type 'Request': context, compress, counter, follow, and 6 more.

 21     new HttpLink({
                     ~
 22       uri: process.env.GRAPHQL_SERVER_ENDPOINT,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
 24       fetch,
    ~~~~~~~~~~~~
 25     }),

This error is basically saying that I have two different type declarations for fetch, and they are incompatible. In other words, apollo-client’s type declaration for fetch doesn’t match node-fetch’s.

Thanks to a few hours of combing through Github issues, I found a solution hidden deep in the comments. In any d.ts file in your project, add:

// real node-fetch types clash with apollo-link-http, so manually define it as globalfetch here.
declare module 'node-fetch' {
  const fetch: GlobalFetch['fetch'];
  export default fetch;
}

I’ve opened an issue on the repo to add this information to the docs. You can find it here.


Mae Capozzi

Hi! I'm Mae Capozzi. You can find me on Twitter and on Github.