its*_*ned 5 typescript typescript-typings
我正在尝试扩展express.Request上可用的express的Request对象,以便它在会话中包含一些其他数据。我尝试创建自己的类型文件(d.ts)并使用以下代码:
import * as express from 'express';
declare module 'express' {
export interface Request {
session: express.Request['session'] & {
myOwnData: string;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
'session' is referenced directly or indirectly in its own type annotation.
Run Code Online (Sandbox Code Playgroud)
实现这一点的正确方法是什么?
因此,查看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;
};
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,编译器似乎对此文件中的导入有些灵活(就像它似乎不关心或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);
Run Code Online (Sandbox Code Playgroud)
经测试,此结构在添加的属性上实现了类型安全,并在 VSCode 和 WebStorm 中实现了智能感知/自动完成express-session以及添加的属性。
不幸的是,正如您所指出的,这不会在使用类型推断的情况下全局应用(仅在您显式 import 的情况下Request)。如果您想完全控制界面,您可以卸载@types/express-session并复制并修改 d.ts(然后导入)。另一种可能性是声明一个全新的属性并实施,但显然需要更多的工作。
| 归档时间: |
|
| 查看次数: |
1890 次 |
| 最近记录: |