TypeScript 通用获取函数,BodyInit 的类型错误

TypeScript generic fetch function, wrong type for BodyInit

我不明白这个错误。它说 toBody() return 是 Blob 类型。但对我来说它应该 return 一个被 BodyInit

接受的字符串

type BodyInit = Blob | BufferSource | FormData | URLSearchParams | ReadableStream<Uint8Array> | string;

export class CredentialsRequestBody
  implements RequestBody<CredentialsRequestBody> {
  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 '{"username":"jonas", "password": "something"}'; //JSON.stringify(Object.assign({}, this)).toString();
  }
type methods = 'DELETE' | 'POST' | 'GET' | 'POST';
export async function request(
  url: string,
  method: methods,
  headers: any,
  body: RequestBody<any>
): Promise<any> {
  const defaultHeaders = {
    'Content-Type': 'application/json'
  };

  const requestOptions: RequestInit = {
    method: method !== null ? method : 'GET',
    headers:
      headers !== null
        ? {
            ...defaultHeaders,
            ...headers
          }
        : defaultHeaders
  };
  if (
    body !== null &&
    requestOptions.method !== 'GET' &&
    requestOptions.method !== 'DELETE'
  ) {
    requestOptions.body = body.toBody();
  }

  const response = await fetch(url, requestOptions);//<--requestOptions INVALID
  return response.json();
}
fetch/index").RequestInit'.
  Types of property 'body' are incompatible.
    Type 'BodyInit' is not assignable to type 'import("/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index").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.

即使将字符串转换为 Blob 并将其作为 RequestInit.body 直接传递也会产生相同的错误。类型可以关闭吗?

  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 &&
    requestOptions.method !== 'GET' &&
    requestOptions.method !== 'DELETE'
  ) {
    requestOptions.body = JSON.stringify({ something: 'something' });
  }*/

  const response = await fetch(url, requestOptions);
  return response.json();
}
Argument of type 'RequestInit' is not assignable to parameter of type 'import("/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index").RequestInit'.
  Types of property 'body' are incompatible.
    Type 'BodyInit' is not assignable to type 'import("/home/jonas/WebstormProjects/mindtherags-backend/node_modules/@types/node-fetch/index").BodyInit'.
      Type 'Blob' is not assignable to type 'BodyInit'.
        Type 'Blob' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]ts(2345)
    body: JSON.stringify({
      something: 'something'
    })

也不行

卸载 @types/node-fetch 并以 BlobJSON.stringify(obj)toBody() 作为正文通过任何方式获取都在请求中产生以下错误

(node:145700) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'Symbol(Request internals)' of null

这是哪个函数node-fetch

const INTERNALS = Symbol('Request internals');

/**
* Check if a value is an instance of Request.
*
* @param   Mixed   input
* @return  Boolean
*/
function isRequest(input) {
   return typeof input === 'object' && typeof input[INTERNALS] === 'object';
}

我怀疑打字稿问题与不同地方的定义冲突有关,因为该错误明确指出您的 BodyInit 类型无法分配给 @types/node-fetch 文件夹中的类型。

RequestInitlib.dom.d.ts 中有一个定义,它与 node-fetch 包中的定义略有不同。例如 dom 允许 BodyInitnull 但 node-fecth 不允许。

郑重声明,我在 Typescript Playground 中没有看到任何错误,但我认为这是对获取函数使用 lib.dom 定义。