30

I started to use Typescript for my nodejs project. For accessing some external API, I use node-fetch to make requests. While setting up a PUT request, an error pops up, saying that the given body is not assignable to type RequestInit:

The error:

Error:(176, 28) TS2345:Argument of type '{ headers: Headers; method: string; body: MyClass; }' is not assignable to parameter of type 'RequestInit'.
  Types of property 'body' are incompatible.
    Type 'MyClass' is not assignable to type 'BodyInit'.
      Type 'MyClass' is not assignable to type 'ReadableStream'.
        Property 'readable' is missing in type 'MyClass'.

MyClass:

class MyClass {
  configId: string;
  adapterType: string;
  address: string;

  constructor(configId: string, adapterType: string, address: string) {
    this.configId = configId;
    this.adapterType = adapterType;
    this.address = address;
  }

  // some methods
}

Invocation:

let body = new MyClass("a", "b", "c")
let url = config.url + "/dialog/" + dialogId
let headers = new Headers()
// Append several headers

let params = {
  headers: headers,
  method: "PUT",
  body: body
}

return new Promise((resolve, reject) => {
  Fetch(url, params) // <-- error is shown for params variable
    .then(res => {
      // Do stuff
      resolve(/*somevalue*/)
    })
}

How should I make the body object compatible?

Leon Joosse
  • 959
  • 1
  • 7
  • 17

3 Answers3

58

You need to stringify your body:

let params: RequestInit = {
  headers: headers,
  method: "PUT",
  body: JSON.stringify(body)
}
Ruslan Korkin
  • 3,973
  • 1
  • 27
  • 23
14

I can think of two possible approaches - one is that setting the headers in a particular way to complement your body type would resolve it.

The other thought is that an instance of a class may not be an appropriate body type. Can you stringify it?

Update: I had a weird error with RequestInit too, and it was resolved by specifying the type of the options (what you called 'params') object, like this:

let params: RequestInit = {
  ...
}
hboo
  • 431
  • 5
  • 10
  • Thanks this helped me! I also had to follow on and define my credentials like this: `credentials: "include" as "include" | "omit" | "same-origin",` – Kitson Jun 08 '20 at 10:23
4

I had to import RequestInit from node-fetch rather than using the inbuilt typescript one.

i.e.

This:

import fetch, { RequestInit } from 'node-fetch'

let params: RequestInit = {
  headers: headers,
  method: "PUT",
  body: JSON.stringify(body)
}

NOT this:

import fetch from 'node-fetch'

let params: RequestInit = {
  headers: headers,
  method: "PUT",
  body: JSON.stringify(body)
}
Resonance
  • 3,359
  • 2
  • 16
  • 20