我正在研究基于express的节点服务器,并使用TypeScript 1.7编写。我正在使用一些特定于项目的中间件,这些中间件扩展了现有的快速请求或响应接口,但是我无法完全使用它(没有tsc抱怨在req
或res
中找不到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);
});
扩展表达式请求和响应接口的最佳做法是什么?如果可能的话,无需编写单独的d.ts,操纵typings目录中的任何内容或使用/// <reference path="..." />
注释。
答案 0 :(得分:1)
我自己找到了一个解决方案,使用this example作为参考。我的中间件需要包装在一个声明的模块中,所以中间件/ 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;
}
如果你在中间件中使用类或其他导入的东西,那就更麻烦了。在我的例子中,我的中间件使用我自己的&#34; EntityManager&#34; class,它是数据库连接的抽象(对我来说是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文件中,其中不存在实际代码。