如何在 Typescript 中正确扩展请求的标头

Jos*_*lho 5 types backend node.js express typescript

我需要userIdin req.headers,但我无法正确输入,我该怎么做?

首先我尝试这样做:

  interface ISpot{
    thumbnail: File,
    company: string,
    price: number,
    techs: string
  }

  interface IReqCustom<T> extends Request{
    body: T,
  }

  export default {
    async store (req: IReqCustom<ISpot>, res: Response): Promise<Response> {
      const { filename } = req.file
      const { company, techs, price } = req.body
      const { userId } = req.headers

      const user = await User.findById(userId)

      if (!user) {
        return res.status(400).json({ error: 'User doesn\'t exist' })
      }

      const spot = await Spot.create({
        user: userId,
        thumbnail: filename,
        company,
        techs: techs.split(',').map(tech => tech.trim()),
        price
      })

      return res.json(spot)
    }

}
Run Code Online (Sandbox Code Playgroud)

第 34行上的用户密钥必然是一个字符串,但它接收值是。userIdstring | string [] | undefined

我也尝试过这个:


interface UserHeader{
  userId: string
}

interface IReqCustom<T, P> extends Request{
  body: T,
  headers: P
}

async store (req: IReqCustom<ISpot, UserHeader>, res: Response): Promise<Response>{}
Run Code Online (Sandbox Code Playgroud)

用户归因中的错误消失,但界面中出现另一个错误IReqCustom

Interface 'IReqCustom<T, P>' incorrectly extends interface 'Request<ParamsDictionary, any, any, ParsedQs>'.
  Types of property 'headers' are incompatible.
    Type 'P' is not assignable to type 'IncomingHttpHeaders'.
Run Code Online (Sandbox Code Playgroud)

如何让这些属性识别它们各自的类型?

gur*_*sko 5

您需要采用IncomingHttpHeaders(这是由 返回的类型express.Request.headers)并将其与您的自定义标头类型扩展/相交:

import {Request, Response} from 'express';
import {IncomingHttpHeaders} from 'http';

interface ISpot{
  thumbnail: File,
  company: string,
  price: number,
  techs: string
}

interface CustomHeaders {
  userId: string;
}

interface IReqCustom<TBody, THeader> extends Request {
  body: TBody;
  headers: IncomingHttpHeaders & THeader;
}

export const handler = (req: IReqCustom<ISpot, CustomHeaders>, res: Response) => {
  const {userId} = req.headers; // `userId` is now `string`
  return res.status(200);
}
Run Code Online (Sandbox Code Playgroud)