express:扩展 Express.Request 的项目本地中间件

标签 express typescript typescript1.7

我在基于 express 的节点服务器上工作并用 TypeScript 1.7 编写。我正在使用一些特定于项目的中间件,它们扩展了现有的快速请求或响应接口(interface),但我还不能让它完全工作(没有 tsc 提示在 reqres 中找不到 X)。我找到了其他 questions关于这个问题,但它们要么已经过时(我猜),要么解决方案并不直接。

我看了一下 existing middleware 的定义,但如果不手动编写单独的 d.ts 文件并在 typings/tsd.d.ts 中引用它们,我就无法正常工作。这是我的设置:

// middleware/foobar.ts
declare module Express {
  export interface Request {
    foobar?: string;
  }
}

/* my project-related middleware extends the request by `foobar` */
export = function(req: Express.Request, res, next) {
  req.foobar = 'FooBar';
  next();
};

// main.ts
import express = require('express');

var app = express();

app.use(require('./middleware/foobar'));

app.get('/foobar', (req, res) => {
  /* tsc: Property 'foobar' does not exist on type 'Request' */
  res.send(req.foobar);
});

扩展 express 的请求和响应接口(interface)的最佳实践是什么?如果可能,无需编写单独的 d.ts,在 typings 目录中操作任何内容或使用 /// <reference path="..." />评论。

最佳答案

我自己找到了一个解决方案,使用 this example作为引用。我的中间件需要包装在声明的模块中,所以 middleware/foobar.ts 看起来像这样:

declare module Express {
  export interface Request {
    foobar?: string;
  }
}

declare module 'foobar' {
  function foobar(req: Express.Request, res, next) {
    req.foobar = 'FooBar';
    next();
  }

  export = foobar;
}

如果您在中间件中使用类或其他导入的东西,那就更棘手了。在我的示例中,我的中间件使用我自己的“EntityManager”类,它是对数据库连接(对我来说是 mysql)的抽象。我的中间件(对我来说是 middleware/database.ts)现在看起来像这样:

declare module Express {
  import { Manager as EntityManager } from 'entity-manager';

  export interface Request {
    entityManager?: EntityManager;
  }
}

declare module 'database' {
  import * as mysql from 'mysql';
  import { Manager as EntityManager } from 'entity-manager';

  /* some middleware-related code */
  var pool = mysql.createPool(...);
  var entityManager = new EntityManager(pool);
  /* *** */


  /* the actual exported function */
  function database(req: Express.Request, res, next) {
    req.entityManager = entityManager;
    next();
  };

  export = database;
}

请注意,我的 EntityManager 类被导入了两次,每个模块声明一次。仅将其导入到两个模块之上似乎不起作用。

更新

在声明的模块中包含实际代码(在我的例子中为 'database')不会在 JS 文件中产生任何输出。

在常规模块中包含该代码要求名称不在撇号中(例如,不允许在那里使用连字符)并且也不会生成单功能导出代码。

将实际代码完全脱离模块(因此只有声明的 Express 模块和扩展请求)会生成正确的 JS,但我的文本编辑器找不到 entityManager不再需要了。

似乎我需要将输入(例如,我自己对 Express.Request 的扩展)放入专用的 d.ts 文件中,其中不存在实际代码。

关于express:扩展 Express.Request 的项目本地中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34577790/

相关文章:

javascript - 从 javascript 中调用快速路由

exception - Nodejs 和 Express 中 Passport 的额外验证和异常(exception)

Node.js - 检查用户是否存在

java - 使用 ionic 3 进行 HTTP Post

node.js - TypeScript 没有将 javascript 与 VS 2015 中的 Node.js TS 应用程序合并为单个文件

node.js - 运行 mongoose 更新代码时出错 ( router.patch() )

angular - 禁用滑动以查看sidemenu ionic 2

arrays - Typescript 创建指定长度的空数组

typescript - Typescript 数组文字语法的差异