39

I am using Fetch API from react-native and I am using typescript. My code looks like this:

let responseLogin = await fetch('http://url_example', {
        method: 'POST',
        headers: {'Content-Type':'application/json'},
        body: requestBody
    });

But I get the following error where the header is:

 Argument of type '{ method: string; headers: { 'Content-Type': string; }; body: string; }' is not assignable to parameter of type 'RequestInit'.
  Types of property 'headers' are incompatible.
    Type '{ 'Content-Type': string; }' is not assignable to type 'Headers | string[][]'.
      Object literal may only specify known properties, and ''Content-Type'' does not exist in type 'Headers | string[][]'.

I have also tried to create a custom header but without any luck:

    let requestHeaders = new Headers();
        requestHeaders.set('Content-Type', 'application/json');
        // I have also tried adding this at the end but no luck 
        // requestHeaders.get('Content-Type');

How could I add a header to this? Because I cannot find any way to make this happen and I don't know what is the problem. If I test these in postman, I get a 200 response, here I get a 401 response. I have also tried this library just to add custom headers: https://www.npmjs.com/package/fetch-headers

I use: Visual studio code 1.81.1 "react-native": "0.50.0", "typescript": "2.6.1"

5
  • 1
    does it require any credentials to be send ? Commented Dec 11, 2017 at 13:46
  • 1
    have you tried using headers: { Accept: 'application/json', 'Content-Type': 'application/json', } in the fetch api Commented Dec 11, 2017 at 13:47
  • 1
    you may need to add credentials: 'include' in the fetch request if you are sending credentials Commented Dec 11, 2017 at 13:50
  • 1
    @Niladri I am sending a username and a password. Yes I have tried with your second suggestion and it said the same thing. I have not tried with credentials, I will trie and come back with an answer. Commented Dec 11, 2017 at 14:01
  • 1
    @Niladri I have tried with credentials: 'include', it is still not working. Commented Dec 11, 2017 at 14:39

6 Answers 6

77
+100

Can you try typing it as HeadersInit?

const requestHeaders: HeadersInit = new Headers();
requestHeaders.set('Content-Type', 'application/json');

const responseLogin = await fetch('URL', {
  method: 'POST',
  headers: requestHeaders,
  body: requestBody
});

If not, can you show the error you are getting when you are initiating it with the Headers() constructor, you showed in the question?

Sign up to request clarification or add additional context in comments.

5 Comments

Same problem here, here's the error I get when typing it as HeadersInit: Type 'Headers' is not assignable to type 'Headers | string[][] | { [key: string]: string; } | undefined'. (How is type Headers not assignable to type Headers | ...?)
What is the typescript version you are using in your package.json?
It’s ^3.2.2, added automatically by the Firebase cloud functions setup
Oke, that isn't the issue then. But you are not required to give a type, so you can also only do const requestHeaders = new Headers();
The type in the HeadersInit contains other types, not only Headers, so you actually should not put the type there.
7

What TypeScript libraries are you including with your build? It looks like your definition for the headers property is wrong. In TypeScript 2.6.2, the headers property is of type HeadersInit, which is defined as: type HeadersInit = Headers | string[][] | { [key: string]: string };

2 Comments

I have tried to add the headers like this: headers: [['Content-Type'] , ['application/json']]. Still it returns a status of 401.
I have also tried this library: npmjs.com/package/fetch-headers
6

I solved the problem by importing Headers like this:

import fetch, { Headers } from 'node-fetch';

Comments

4

The accepted answer has the caveat that it doesn't handle the scenario where you encapsulate fetch into a function of your own that receives the same arguments as fetch and sets defaults to the headers property. For example:

async function myFetch(input: RequestInfo, init: RequestInit) {
  // set some headers here
  const res = await fetch(input, init)
  // return something from the response here, handle errors
}

The problem with the resolved answer is that RequestInit.headers is of type HeadersInit whose definition is:

type HeadersInit = string[][] | Record<string, string> | Headers;

When I try to set defaults for headers but still use headers passed by the calling function, I run into issues because of these possible multiple types that I need to deal with.

What I resolved out of complete exasperation is to define my own RequestInit type where headers is only Record<string, string>. I don't care about the other types, an object of string key/values IS fine.



export interface MyRequestInit extends Omit<RequestInit, 'headers'> {
  headers?: Record<string, string>;
}

export async function fetchJson<JSON = unknown>(
  input: RequestInfo,
  init: MyRequestInit = {},
) {
  // set my own default headers here
  const res = await fetch(input, init)
  // ...
}

Comments

3

I faced the same issue but the accepted answer would not work in my case because headers might have been already initialized. So

    if (!requestInit.headers) {
      requestInit.headers = new Headers()
    }

    requestInit.headers.set('Content-Type', 'application/json')
    // *TS2339: Property 'set' does not exist on type 'HeadersInit'. Property 'set' does not exist on type 'string[][]'*

Produces compilation error because, like others pointed out, HeadersInit is defined as type HeadersInit = string[][] | Record<string, string> | Headers;

FIX: use constructor with param

requestInit.headers = new Headers(requestInit.headers)
requestInit.headers.set('Content-Type', 'application/json')

Comments

0

It's 2024, your question is still relevant, and now you can cast the object you pass as a HeadersInit :

let responseLogin = await fetch('http://url_example', {
        method: 'POST',
        headers: {'Content-Type':'application/json'} as HeadersInit,
        body: requestBody
    });

On my system, tsc stops complaining with this cast. To be exact, I haven't tested this with tsc 2.6 (mine is 5.6.3).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.