10

I am trying to use the Fetch API in TypeScript, but for some reason I am getting

Type 'string' is not assignable to type 'RequestMode'.

Here is my code

export class MainService{
  constructor(){}
  request(requestObj){
    if (!requestObj.url) {
      return 'Please provide the end point url'
    }
    else {
     let requestParam = {
        method: requestObj.method ? requestObj.method : 'GET',
        headers: new Headers(),
        mode: 'cors'
      };
      fetch(endPointHost+requestObj.url,requestParam).then(function(resp){
                                        //^^^ error thrown here
        resp.json();
      })
    }
     console.log(" Reached request");
  }

}

The error reported is

TS2345: Argument of type '{ method: any; headers: Headers; mode: string; }' is not assignable to parameter of type 'RequestInit'. Types of property 'mode' are incompatible. Type 'string' is not assignable to type 'RequestMode'.

brk
  • 48,835
  • 10
  • 56
  • 78
  • 4
    Does `let requestParam: RequestInit = { …` work? – Ry- Dec 17 '17 at 07:28
  • 1
    `requestObj.url === undefined && requestObj.url === ''` is a buf a variable cannot be `undefined` and `''` at the same time. try `if (!requestObj.url) { ... }` instead – notrota Dec 17 '17 at 07:31
  • @Ryan thanks Sir it worked, i am trying to find out the reason why it worked – brk Dec 17 '17 at 07:44
  • @GuyWhoKnowsStuff I completely agree with you, that was my mistake, have make the change – brk Dec 17 '17 at 07:45
  • sarcasm? :) i wasnt trying to answer just saw a bug – notrota Dec 17 '17 at 07:47
  • @GuyWhoKnowsStuff nope it was not sarcasm, actually you are right – brk Dec 17 '17 at 07:48
  • The reason behind this is that TypeScript does a kind of limited form of type inference, so when you have the statement `let requestParam = { … };`, `requestParam` will always get the same type regardless of how it’s used later, and that type has `mode: string`. – Ry- Dec 17 '17 at 08:08
  • The reason is discussed here: https://stackoverflow.com/questions/47606183/how-can-i-hint-to-the-typescript-compiler-to-infer-string-literal-types-for-prop – artem Dec 17 '17 at 10:57

2 Answers2

16

This worked for me: mode: 'cors' as RequestMode,

ianhowe76
  • 161
  • 1
  • 4
9

The problem here is that requestParam could potentially be modified in an way that it does not respect RequestInit interface later. You can either declare that requestParam implements RequestInit at creation:

let requestParam: RequestInit = {
    method: requestObj.method ? requestObj.method : 'GET',
    headers: new Headers(),
    mode: 'cors'
};

or put request parameters directly inside the fetch call:

fetch(endPointHost+requestObj.url, {
    method: requestObj.method ? requestObj.method : 'GET',
    headers: new Headers(),
    mode: 'cors'
}).then(function(resp){
    resp.json();
})
Frank Bessou
  • 632
  • 5
  • 8