6

I am trying to make a request using node-fetch in my typescript project and I do not understand how to fix the compilation error or what it actually tries to tell me.

I've updated all packages (including the global typescript package) to the latest versions.

I've created a gist that isolates the error: https://gist.github.com/HerrZatacke/ae90f608e042864b6e00e9c73a950602

This (very short) script is able to reproduce the compilation error:

import fetch from 'node-fetch';

const toJson = (response: Response):PromiseLike<object> => (
  response.json()
);

const makeSomeRequest = (): Promise<object> => {
  return fetch('https://some-api.com/')
    .then(toJson)
};

makeSomeRequest();

The installed versions used are

@types/node-fetch 2.3.7
node-fetch2.6.0
typescript 3.5.2

the actual error is

example.ts:9:11 - error TS2345: Argument of type '(response: Response) => PromiseLike<object>' is not assignable to parameter of type '(value: Response) => object | PromiseLike<object>'.
  Types of parameters 'response' and 'value' are incompatible.
    Type 'Response' is missing the following properties from type 'Response': redirected, trailer, formData
HerrZatacke
  • 273
  • 2
  • 10
  • 1
    Looks like two different types with the same name `Response` to me. – Bergi Jul 03 '19 at 20:34
  • Okay, sounds plausible. As I am quite new to typescript, this is not meant to happen? – HerrZatacke Jul 03 '19 at 20:41
  • 1
    Typings for node-fetch `Response` doesn't have those 3 properties as you can see in the source code: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/29ca96dcfea1a0b3d07f0d4dda5445d8990f12dd/types/node-fetch/index.d.ts#L159 Why don't you use the native `Promise` type instead of `PromiseLike`? – brubs Jul 04 '19 at 07:37
  • Using `Promise` instead of `PromiseLike` unfortunately causes the same error – HerrZatacke Jul 04 '19 at 11:08

1 Answers1

17

With the help/hints of the two commenters above (thanks a lot), I managed to find the reason and a solution for that error:

Typescript initially tries to "guess" which types you are using.

The following line states I want to use the type response, which is an interface of the native Fetch API

const toJson = (response: Response): Promise<object> => {

the type definition for it can be found in lib.dom.d.ts

node-fetch instead is implementing it's own Response type from @types\node-fetch\index.d.ts

So, if the correct response type is being imported first, the typescript compiler runs without the error.

Which means, instead of just importing node-fetch, you also have to import it's definition of Response:

import fetch, { Response } from 'node-fetch';
HerrZatacke
  • 273
  • 2
  • 10