Typescript - HeadersInit 类型上不存在“授权”

use*_*322 8 typescript node-fetch

我正在使用node-fetchnpm 模块,并有一个辅助函数来向第三方服务发出授权请求(基本上只是用于添加授权标头的中间件)。

async function makeAuthorizedRequest(url: string, options: RequestInit) {
  if (!options) {
    options = { headers: {} as HeadersInit }
  }
  if (!options.headers) {
    options.headers = {} as HeadersInit
  }
  options.headers.Authorization = `Bearer ${access_token}`
  if (!options.headers['User-Agent']) {
    options.headers['User-Agent'] = USERAGENT
  }
  return fetch(url, options)
}
Run Code Online (Sandbox Code Playgroud)

RequestInit类型被定义为具有如下定义的headers类型属性HeadersInit

export type HeadersInit = Headers | string[][] | { [key: string]: string };
Run Code Online (Sandbox Code Playgroud)

我在 IDE (VSCode) 中遇到两个不同的错误,并tsc拒绝编译它,因为

Property 'Authorization' does not exist on type 'Headers'.ts(2339)
Run Code Online (Sandbox Code Playgroud)

Element implicitly has an 'any' type because expression of type '"User-Agent"' can't be used to index type 'HeadersInit'.
  Property 'User-Agent' does not exist on type 'HeadersInit'.ts(7053)

Run Code Online (Sandbox Code Playgroud)

现在显然“User-Agent”和“Authorization”是有效的http标头,根据我的理解,类型{[key: string]: string}定义应该允许这种情况,因为“User-Agent”和“Authorization”是字符串,并且它们的值被设置为字符串。为什么 tsc 无法看到这一点以及我该如何修复它?

(我//@ts-ignore过去曾在受影响的线路上使用过,但我想了解它关心什么以及将来如何解决这个问题 - 因为在整个代码库中使用 ts-ignore 看起来并不专业)

Zol*_*lni 7

这是解决方案:

const headersInit: HeadersInit = {};
options.header = headersInit;
Run Code Online (Sandbox Code Playgroud)

一般来说,如果可能的话,您希望避免类型断言 ( as)。

替代解决方案:如果您知道options.headers既不是 aHeaders也不是 a,string[][] 您可以这样做:

options.headers = {} as { [key: string]: string }
Run Code Online (Sandbox Code Playgroud)

或同等的

options.headers = {} as Record<string, string>
Run Code Online (Sandbox Code Playgroud)