无法延长加急请求

问题描述 投票:0回答:2

我正在尝试将

Request
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');
  }
});

但我收到以下错误:

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

typescript express typescript-types
2个回答
6
投票

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

router.get('/', auth, async (req: IRequest, res: Response) => {

Typescript 仍然会假设 Express 会发出

Request
而不是
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');
}

1
投票

假设接口

IRequest
除上述用途外没有用于其他目的,可以按照Antonello Zanini的这篇博客文章中的路线:只需通过添加声明文件来扩展express定义的接口
 src/types/express/index.d.ts
包含以下内容:

// src/types/express/index.d.ts

// to make the file a module and avoid the TypeScript error
export {}

declare global {
  namespace Express {
    export interface Request {
      user: {
        id: string;
      }
    }
  }
}

与另一个答案一样,TypeScript 的 声明合并 机制会将两个声明融合为一个。

希望这个迟来的答案对一些读者有用。我刚刚有一个类似的问题

© www.soinside.com 2019 - 2024. All rights reserved.