无法延长快速请求

sfa*_*oso 3 express typescript

我正在尝试扩展asRequest的接口Express

import express, { Request, Response } from 'express';
interface IRequest extends Request {
  user: {
    id: string;
  }
}

const router = express.Router();

router.get('/', auth, async (req: IRequest, res: Response) => {
  try {
    const user = await User.findById(req.user.id).select('-password');
    res.json(user);
  } catch (e) {
    console.error((e as Error).message);
    res.status(500).send('Server Error');
  }
});
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

没有重载与此调用匹配。重载第 1 个(共 3 个)“(path: PathParams, ...handlers: RequestHandler<ParamsDictionary, any, any, ParsedQs>[]): Router”,出现以下错误。类型“(req: IRequest, res: Response) => Promise”的参数不可分配给类型“RequestHandler<ParamsDictionary, any, any, ParsedQs>”的参数。参数“req”和“req”的类型不兼容。类型“Request<ParamsDictionary,any,any,ParsedQs>”中缺少属性“user”,但类型“IRequest”中需要属性“user”。重载 2 of 3, '(path: PathParams, ...handlers: RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>[]): Router',出现以下错误。类型“(req: IRequest, res: Response) => Promise”的参数不可分配给类型“RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>”的参数。类型“(req: IRequest, res: Response) => Promise”不可分配给类型“RequestHandler<ParamsDictionary, any, any, ParsedQs>”.ts(2769)

Eve*_*ert 6

Typescript 不会让你这么做,因为即使你这样输入:

router.get('/', auth, async (req: IRequest, res: Response) => {
Run Code Online (Sandbox Code Playgroud)

Typescript 仍会假设express 将发出 aRequest而不是IRequest

然而,由于您可能正在对请求对象进行猴子修补,因此您可以使用声明合并来基本上增强 Express 的内部请求对象:

https://www.typescriptlang.org/docs/handbook/declaration-merging.html

如果您不想全局地对 进行此更改Request,您还可以使用断言来确保它确实是一个IRequest

router.get('/', auth, async (req: request, res: Response) => {
  try {
    assertIRequest(req);
    const user = await User.findById(req.user.id).select('-password');
    res.json(user);
  } catch (e) {
    console.error((e as Error).message);
    res.status(500).send('Server Error');
  }
});

function assertIRequest(req: Request|IRequest): asserts req is IRequest {
  if (!req?.user?.id) throw new Error('Request was not an IRequest');
}
Run Code Online (Sandbox Code Playgroud)