title: TypeScript generic fetch function, wrong type for BodyInit
body: <p>I don't understand this error. It says <code>toBody()</code> returns a <code>Blob</code> type. but to me it should return a string which is accepted by <code>BodyInit</code></p>
  <p><code>type BodyInit = Blob | BufferSource | FormData | URLSearchParams | ReadableStream&lt;Uint8Array&gt; | string;</code></p>
  <pre><code>export class CredentialsRequestBody
    implements RequestBody&lt;CredentialsRequestBody&gt; {
    constructor(username: string, password: string) {
      this.username = username;
      this.password = password;
    }
    username: string;
    password: string;
    toBody(): BodyInit {
      console.log(typeof JSON.stringify(Object.assign({}, this)).toString());
      return '{&quot;username&quot;:&quot;jonas&quot;, &quot;password&quot;: &quot;something&quot;}'; //JSON.stringify(Object.assign({}, this)).toString();
    }
  </code></pre>
  <pre><code>type methods = 'DELETE' | 'POST' | 'GET' | 'POST';
  export async function request(
    url: string,
    method: methods,
    headers: any,
    body: RequestBody&lt;any&gt;
  ): Promise&lt;any&gt; {
    const defaultHeaders = {
      'Content-Type': 'application/json'
    };
  
    const requestOptions: RequestInit = {
      method: method !== null ? method : 'GET',
      headers:
        headers !== null
          ? {
              ...defaultHeaders,
              ...headers
            }
          : defaultHeaders
    };
    if (
      body !== null &amp;&amp;
      requestOptions.method !== 'GET' &amp;&amp;
      requestOptions.method !== 'DELETE'
    ) {
      requestOptions.body = body.toBody();
    }
  
    const response = await fetch(url, requestOptions);//&lt;--requestOptions INVALID
    return response.json();
  }
  </code></pre>
  <pre><code>fetch/index&quot;).RequestInit'.
    Types of property 'body' are incompatible.
      Type 'BodyInit' is not assignable to type 'import(&quot;/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index&quot;).BodyInit'.
        Type 'Blob' is not assignable to type 'BodyInit'.
          Type 'Blob' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]
  
  29   const response = await fetch(url, requestOptions);
                                         ~~~~~~~~~~~~~~
  
  [9:40:22 PM] Found 1 error. Watching for file changes.
  </code></pre>
  <p>even converting a string to a <code>Blob</code> and passing it directly as <code>RequestInit.body</code> yields the same error. Could the type be off?</p>
  <pre><code>  const requestOptions: RequestInit = {
      method: method !== null ? method : 'GET',
      headers:
        headers !== null
          ? {
              ...defaultHeaders,
              ...headers
            }
          : defaultHeaders,
      body: new Blob([JSON.stringify({ something: 'something' })], {
        type: 'text/plain'
      })
    };
    /*if (
      body !== null &amp;&amp;
      requestOptions.method !== 'GET' &amp;&amp;
      requestOptions.method !== 'DELETE'
    ) {
      requestOptions.body = JSON.stringify({ something: 'something' });
    }*/
  
    const response = await fetch(url, requestOptions);
    return response.json();
  }
  </code></pre>
  <pre><code>Argument of type 'RequestInit' is not assignable to parameter of type 'import(&quot;/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index&quot;).RequestInit'.
    Types of property 'body' are incompatible.
      Type 'BodyInit' is not assignable to type 'import(&quot;/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index&quot;).BodyInit'.
        Type 'Blob' is not assignable to type 'BodyInit'.
          Type 'Blob' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]ts(2345)
  </code></pre>
  <pre><code>    body: JSON.stringify({
        something: 'something'
      })
  </code></pre>
  <p>does not work either</p>
  <p>uninstalling <code>@types/node-fetch</code> and fetching through anyways with <code>Blob</code>, <code>JSON.stringify(obj)</code> and <code>toBody()</code> as the body all yield the following error on the request</p>
  <pre><code>(node:145700) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'Symbol(Request internals)' of null
  </code></pre>
  <p>which is this function <code>node-fetch</code></p>
  <pre class="lang-js prettyprint-override"><code>const INTERNALS$2 = Symbol('Request internals');
  
  /**
  * Check if a value is an instance of Request.
  *
  * @param   Mixed   input
  * @return  Boolean
  */
  function isRequest(input) {
     return typeof input === 'object' &amp;&amp; typeof input[INTERNALS$2] === 'object';
  }
  </code></pre>