fetch's type not matching when calling createHttpLink

Viewed 2008

Following the instructions here:

https://www.apollographql.com/docs/react/performance/server-side-rendering/#server-side-rendering

to do server side rendering I run into this error:

Invariant Violation:
fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/node-fetch.

For example:
import fetch from 'node-fetch';
import { createHttpLink } from 'apollo-link-http';

const link = createHttpLink({ uri: '/graphql', fetch: fetch });

I added the recommended code, importing fetch, passing it to createHttpLink, I also installed @types/node-fetch, but I'm getting this warning/error:

Error:(75, 7) TS2322: Type 'typeof fetch' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
  Types of parameters 'url' and 'input' are incompatible.
    Type 'RequestInfo' is not assignable to type 'import("C:/Users/pupeno/Documents/Flexpoint Tech/js/exp5/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.

The type of the fetch function I'm passing, defined on node-fetch/index.d.ts is:

declare function fetch(
    url: RequestInfo,
    init?: RequestInit
): Promise<Response>;

while the expected type of fetch is:

fetch?: WindowOrWorkerGlobalScope['fetch'];

I'm not sure exactly how to find WindowOrWorkerGlobalScope, my IDE points to two possible definitions, one in dom:

fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

and one in webworker:

fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

They seem identical.

I can keep going down the rabbit hole of types but does this ring a bell? Should I be using a different fetch?

1 Answers

node-fetch doesn't implement the complete Fetch API—only a subset that makes sense on Node.js.

However, it is very unlikely that createHttpLink uses those unimplemented parts. So it should be safe to disable the type checking here:

const link = createHttpLink({ uri: '/graphql', fetch: fetch as any });

It may be worth filing an issue to the Apollo project, asking them to restrict their expected type to what is actually used.

Related