我正在尝试扩展 express.Request 上提供的快递的请求对象,以便它包含其中的一些其他数据会话。我尝试创建自己的打字文件( d.ts )并使用以下代码:
import * as express from 'express';
declare module 'express' {
export interface Request {
session: express.Request['session'] & {
myOwnData: string;
}
}
}
我受到以下错误:
的欢迎'session' is referenced directly or indirectly in its own type annotation.
实现此目的的正确方法是什么?
答案 0 :(得分:2)
因此,查看express-session
类型声明,它在Session
命名空间下声明了Request
(和修改后的Express
对象)。使用这个我们可以创建一个类型声明(mySession.dt.s
)来扩充默认属性,绕过声明合并的限制:
import {Express} from 'express';
import 'express-session';
declare module 'express' {
export interface Request {
session: Express.Session & {
myOwnData: string;
myOwnData2: number;
myOwnData3: boolean;
};
}
}
请注意,编译器似乎对此文件中的导入有一定的灵活性(如果导入Express
或Request
似乎并不关心),但显式是最大的是一致的。
然后我们可以将此声明导入我们的服务器文件:
import express = require('express');
import {Express, Request, Response} from 'express';
import './mySession';
import * as session from 'express-session';
const app: Express = express();
const PORT = process.env.PORT || process.env.NODE_PORT || 3000;
app.use('/endpoint', (req: Request, res: Response) => {
const a: number = req.session.myOwnData3 + 2; // fails to compile and highlighted by editors
console.log(req.session.myOwnData); // compiles and provided autocomplete by Webstorm
// do stuff
return res.ok();
});
app.use(session(/** do session stuff **/));
log.info(`Start Express Server on ${PORT}`);
app.listen(PORT);
经过测试,此结构在添加的属性上实现了类型安全性,并在VSCode和WebStorm中同时使用express-session
和添加的属性实现智能感知/自动完成。
不幸的是,正如您所指出的,在使用类型推断的情况下,这不会全局应用(仅限于您明确导入Request
的地方)。如果您想完全控制界面,可以卸载@types/express-session
并复制&修改d.ts(并导入)。另一种可能性是宣布一个全新的财产和实施,但显然还有更多的工作。