Typescript -“Authorization”在类型HeadersInit上不存在

rfbsl7qr  于 2023-11-20  发布在  TypeScript
关注(0)|答案(3)|浏览(261)

我使用的是node-fetch npm模块,它有一个helper函数,用于向第三方服务发出授权请求(基本上只是用于添加Authorization头的中间件)。

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)
}

字符串
RequestInit类型定义为具有HeadersInit类型的headers属性,定义如下

export type HeadersInit = Headers | string[][] | { [key: string]: string };


我在IDE(VSCode)中得到两个明显的错误,tsc拒绝编译它,因为

Property 'Authorization' does not exist on type 'Headers'.ts(2339)


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)


现在很明显“User-Agent”和“Authorization”是有效的http头,根据我的理解,类型{[key: string]: string}定义应该允许这样做,因为“User-Agent”和“Authorization”是字符串,它们的值被设置为字符串。为什么tsc不能看到这一点,我如何才能真正修复它?
(我过去在受影响的行上使用过//@ts-ignore,但我想了解它关注的是什么以及将来如何解决这个问题-因为在代码库中使用ts-ignore看起来并不专业)

yqlxgs2m

yqlxgs2m1#

解决方案如下:

const headersInit: HeadersInit = {};
options.header = headersInit;

字符串
一般来说,如果可能的话,你应该避免类型Assert(as)。
另一种解决方案:如果你知道options.headers既不是Headers也不是string[][],你可以这样做:

options.headers = {} as { [key: string]: string }

yrwegjxp

yrwegjxp2#

我通过意识到HeadersInitHeaders是两种不同的类型来解决这些错误。因此,如果有人面临类似的问题,请尝试以下操作:

const headers = options?.headers ? new Headers(options.headers) : new Headers();
    
if (!headers.has("Authorization")) {
    headers.set("Authorization", `Bearer ${authToken});
}

字符串
这和问题不完全一样,但我认为这值得分享。

pxy2qtax

pxy2qtax3#

HeadersInit类型没有定义更改项目的方法。但它被定义为与string[][]Record<string, string>Headers兼容。使用一个Headers对象,您可以轻松地将其用作HeadersInit文字对象的替代品,您的代码可以重写为:

async function makeAuthorizedRequest(url: string, options: RequestInit) {
    // Redefining is unnecessary because the parameter must be a defined RequestInit.
    //if (!options) {
    //  options = {} as RequestInit;
    //}
    // A Headers object can be assigned to HeadersInit.
    // const means the variable is immutable, not its content.
    const reqHeaders = new Headers(options.headers);
    // Use `set` in case a header already exists in the collection.
    reqHeaders.set('Authorization', `Bearer ${access_token}`);
    if (!reqHeaders.get('User-Agent')) {
      reqHeaders.set('User-Agent', USERAGENT);
    }
    // Use the updated headers collection in the request.
    options.headers = makeHeaders;
    return fetch(url, options);
  }

字符串
我假设你已经分配了access_tokenUSERAGENT

相关问题