【问题标题】:Extending existing properties on @types declarations在 @types 声明上扩展现有属性
【发布时间】:2018-06-16 05:08:35
【问题描述】:

我正在尝试扩展 express.Request 上可用的 expressRequest 对象,以便它在会议。我尝试创建自己的类型文件 (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的帖子
  • 为什么不创建自己的请求? interface MyRequest extends Request { session: string }
  • 因为当我这样做时,我的打字稿程序仍在使用原始界面而不是新界面。我将不得不手动导入并在任何地方使用另一个名称,除非我没有看到其他方式
  • 尝试使用声明合并直接扩展静态类型。请注意,我没有找到声明 session 的 d.ts(我在移动设备上)。其次,您可以尝试在之前键入别名并将别名类型用作session 的静态类型。
  • 会话正在由 express-session 模块添加。声明合并只是添加新类型而不是扩展它们。如果我想在请求界面中添加其他内容,我可以做到。我不能做的是更新请求中的会话。我也尝试使用类型别名来导入 Request 但程序仍将使用原始 Request 接口而不是更新的接口。

标签: typescript typescript-typings


【解决方案1】:

所以查看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;
        };
    }
}

请注意,编译器似乎对该文件中的导入有点灵活(就像它似乎并不关心是否导入了 ExpressRequest),但明确将是最一致的。

然后我们可以将此声明导入到我们的服务器文件中:

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(并导入它)。另一种可能性是声明一个全新的属性并实现,但显然还有很多工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多