我正在尝试扩展 express.Request 上可用的 Request 对象,以便它在 session 。我尝试创建自己的类型文件 (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.
实现这个的正确方法是什么?
最佳答案
所以看着 express-session
类型声明,它在 Express
命名空间下声明了一个 Session
(和修改过的 Request
对象)。使用它我们可以创建一个类型声明 (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(并导入它)。另一种可能性是声明一个全新的属性并实现,但显然需要做更多的工作。
关于typescript - 扩展@types 声明的现有属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48129668/