Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
express:项目本地中间件扩展express.Request_Express_Typescript_Typescript1.7 - Fatal编程技术网

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

express:项目本地中间件扩展express.Request,express,typescript,typescript1.7,Express,Typescript,Typescript1.7,我正在一个基于TypeScript 1.7并用它编写的节点服务器上工作。我正在使用一些特定于项目的中间件,它们扩展了现有的express请求或响应接口,但我还不能让它完全工作(tsc没有抱怨在req或res中找不到X)。关于这个问题,我已经找到了其他解决方案,但它们要么已经过时(我想),要么解决方案不直接 我查看了an的定义,但是如果不手动编写单独的d.ts文件并在typings/tsd.d.ts中引用它们,我就无法让它工作。这是我的设置: //中间件/foobar.ts 声明模块Express

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

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

//中间件/foobar.ts
声明模块Express{
导出接口请求{
foobar?:字符串;
}
}
/*我的项目相关中间件通过'foobar'扩展请求*/
导出=功能(请求:快速请求、恢复、下一步){
req.foobar='foobar';
next();
};
//梅因酒店
导入快件=需要(“快件”);
var-app=express();
应用程序使用(要求('./中间件/foobar');
app.get('/foobar',(req,res)=>{
/*tsc:类型“请求”上不存在属性“foobar”*/
res.send(请求foobar);
});

扩展express的请求和响应接口的最佳实践是什么?如果可能的话,无需编写单独的d.T,在typings目录中操作任何内容或使用
//
注释。

我自己找到了一个解决方案,用作参考。我的中间件需要包装在声明的模块中,因此middleware/foobar.ts如下所示:

declare module Express{
导出接口请求{
foobar?:字符串;
}
}
声明模块“foobar”{
函数foobar(请求:快速请求、res、next){
req.foobar='foobar';
next();
}
出口=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,但我的文本编辑器在req中再也找不到
entityManager


似乎我需要将打字(例如我自己的扩展名Express.Request)放入一个专用的d.ts文件中,其中没有实际的代码。

您可以让tsc使用定义标志为您的代码生成d.ts文件。您需要做的就是代码应该实现/扩展请求/响应接口/classes@toskv如果我将tsconfig.json中的
声明设置为true,tsc会抱怨
exports=function
语句,因为它是“使用私有名称'Express.Request'”,即使我在这里向Express.d.ts文件添加了
。编译后(使用
tsc
tsc-w
查看更改),会出现main.d.ts,但由于上述原因,可能会缺少middleware.d.ts。main.ts仍在抱怨缺少req.foobar…这听起来更像是您不能扩展express.request,因为它被定义为private.:(但键入现有express中间件(以示例为例)让它工作起来。我使用
tsc install express session--save
,调查了它的工作原理。它添加了对typings/tsd.d.ts的引用,但一旦我删除了该引用,它就再也找不到
req.session
。我自己也不想修改tsd.d.ts,因为有了下一个tsd命令,我的硬编码引用可能被删除不要删除。你不应该这样做,你不是有一个tsconfig.json和package.json文件来管理依赖关系吗?你找到合适的解决方案了吗?至少我不太理解你在“更新”中写的东西。。