如何使用 express 中间件处理类型?

Posted

技术标签:

【中文标题】如何使用 express 中间件处理类型?【英文标题】:How can I handle type with middleware of express? 【发布时间】:2017-09-11 18:40:35 【问题描述】:

我在 Node.js 中使用 Typescript。当您使用 Express 中间件时,您通常会转换 Request 对象。然而,使用 Typescript,我们无法跟踪 Request 对象是如何转换的。如果你知道之前通过的中间件,有没有办法从中找出请求的类型?如果无法表达,我想在可能的情况下找到另一个框架。在 Nest (https://github.com/kamilmysliwiec/nest) 中可以吗?

示例代码

import  Request, Response, NextFunction  from 'express';

function userMiddleware(req: Request & User, res: Response, next: NextFunction) 
    req.user = 
        id: 'user_id',
    ;
    next();


interface User 
    user: 
        id: string;
    


interface Middleware 
    <T>(req: Request & T, res: Response, next: NextFunction): void;


class Controller 
    middleware = [userMiddleware];

    get = new GetMethod(this.middleware);

    post = (req: Request /* I don't know exact req type */, res: Response, next: NextFunction) => 
        console.log(req.user) // Error!
    


class GetMethod 
    constructor(middleware: Middleware[]) 
        // How to deduce type of req from Middleware array?
    


const controller = new Controller();

express.use('/', controller.middleware, controller.post);

我想从 Controller 类的中间件列表中提取类型信息。

【问题讨论】:

您能提供演示您的问题的示例代码吗? @elithrar 我添加了一些示例代码。谢谢。 我相信nestjs在后台使用express 【参考方案1】:

首先我认为正确的界面是

interface User 
  id: string;


因为它们是回调,所以它们会收到默认的Request,其签名中没有user

因此,您有 2 个选项,进行类型断言或编写自定义声明。如果你做得好,两者都很好。


类型断言:

interface User 
  id: string;


const isObject = (value: unknown): value is [key: string]: unknown => 
  return value && typeof value === 'object';
;

const isReqWithUser = (req: Request): req is Request & user: User => 
  return isObject(req) && !!req.user;


class Controller 
  post = (req: Request, res: Response, next: NextFunction) => 
    if (isReqWithUser(req)) 
      console.log(req.user) // now it works
    
    next();
  


自定义声明:

但我们需要了解用户并不总是存在于请求中,我们应该将其标记为可选。

interface User 
  id: string;


declare module 'express' 
  export interface Request 
    user?: User; // adding our custom declaration.
  


class Controller 
  post = (req: Request, res: Response, next: NextFunction) => 
    console.log(req.user) // now it works
    next();
  

【讨论】:

以上是关于如何使用 express 中间件处理类型?的主要内容,如果未能解决你的问题,请参考以下文章

打字稿混淆:如何使用自定义和绝对类型库扩展 Express `Request`?

express中间件

如何终止路由中间件链?

在 Apollo-Server v2 中间件之后如何使用 Express 中间件?

如何在生产环境中使用 Express 和 Parceljs 中间件

如何在 Node/Express 应用程序中处理 api 版本