使用 TypeScript 扩展 Express Request 对象

Posted

技术标签:

【中文标题】使用 TypeScript 扩展 Express Request 对象【英文标题】:Extending Express Request object using TypeScript 【发布时间】:2015-11-05 18:15:48 【问题描述】:

我正在尝试掌握 TypeScript 的窍门以及有关如何使用 node.js 的各种指南,并在将属性通过中间件之前将它们添加到 Request 对象中。

当然,对于类型脚本,必须定义这些属性,所以我尝试在名为 local.d.ts 的文件中定义:

/// <reference path="tsd.d.ts" />
import mysql = require('mysql');
declare module Express 
    export interface Request 
        dbPool: mySql.IPool;
    

然后我尝试从我的主代码文件中调用它:

/// <reference path="typings/tsd.d.ts" />
/// <reference path="typings/local.d.ts" />
...
import express = require('express');
...
var pool = mySql.createPool(
    user: "username",
    ...
);
app.use(function (req, res, next) 
    req.dbPool = pool;
);

但我得到:“‘请求’类型上不存在属性‘dbPool’。” 我做错了什么?

【问题讨论】:

【参考方案1】:

作为解决方法,您可以从express.Request 继承接口:

declare module 'mysql' 
    import express = require('express');

    interface Request extends express.Request 
        dbPool: IPool;
    

然后在您的代码中投射请求:

(<mysql.Request>req).dbPool...

另一种选择是从express.d.ts 中删除函数声明:

declare module "express" 
    import * as http from "http";

    //- function e(): e.Express;
    //-
    //- module e 

        interface I_1 
        

        ...

        interface I_N 
        

    //- 
    //-
    //- export = e;

并将接口扩展为:

declare module 'express' 
    import mysql = require('mysql');

    interface Express 
        dbPool: mysql.IPool;
    

但之后你需要在调用它之前转换模块:

var exp = <express.Express>(<any>express)();

【讨论】:

当我这样做时,会出现一个放置在同一文件中的“测试”界面,但扩展名仍然不起作用。它还会生成“导出分配不能在具有其他导出元素的模块中使用”。原始 express.d.ts 文件中的错误。 这是一个恶性循环问题,我认为是should be reported。我找到了一些解决方法。【参考方案2】:

我知道这是旧的,但 lodash 的“分配”方法似乎对我有用,并且可能更清洁:

import * as _ from "lodash";

...

app.use(function (req, res, next) 
    _.assign(req, dbPool: pool);
);

【讨论】:

刚刚意识到虽然这个解决方案可以让您分配一个属性,但在访问它之后您仍然会遇到问题......所以这实际上不起作用。

以上是关于使用 TypeScript 扩展 Express Request 对象的主要内容,如果未能解决你的问题,请参考以下文章

无法在 TypeScript 中扩展 Express 请求

使用 Typescript 扩展快速响应对象的正确方法

使用 Visual Studio 2012 express 进行 TypeScript、node.js 开发

扩展 TypeScript 声明文件

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

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