在express-session中扩展session对象

avc*_*lle 1 express typescript express-session

我知道这不是一个实际问题,而是需要帮助。

我在打字稿和快速会议上苦苦挣扎,我一直在尝试并试图弄清楚这个问题相当多。

我正在尝试扩展我的会话对象,为此,我正在尝试按照文档中的方式进行类型合并:

我有一个types/session.d.ts要合并的接口如下:

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,例如,在other-folder/some.ts

req.session.userId = user.id;
// Property 'userId' does not exist on type 'Session & Partial<SessionData>'.
Run Code Online (Sandbox Code Playgroud)

但是,如果我Session从导入express-session,它确实有效:

import { Session } from 'express-session'

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}
Run Code Online (Sandbox Code Playgroud)

我对 TypeScript 不太精通,并且不确定是否要在类型定义中导入模块,事件 TypeScript 对此抱怨(警告):

声明了“Session”,但从未读取其值。

我想知道,这是解决问题的正确方法吗?

我能做些什么不同的事情?

亲切的问候!

PS:我的 tsconfig 应该没问题,因为我可以通过代码使用其他类型定义,并且它们工作时没有任何问题。

sli*_*wp2 6

您应该使用模块增强。您还应该从Modules中了解这一点:

在 TypeScript 中,就像在 ECMAScript 2015 中一样,任何包含顶级导入或导出的文件都被视为模块。相反,没有任何顶级导入或导出声明的文件被视为其内容在全局范围内可用的脚本(因此也适用于模块)。

例如:

./src/main.ts:

import express from 'express';
import session from 'express-session';

const app = express();

app.use(
  session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true },
  }),
);
app.get('/', (req, res) => {
  const user = { id: '1' };
  req.session.userId = user.id;
});
Run Code Online (Sandbox Code Playgroud)

./types/session.d.ts:确保至少包含一个顶级文件importexport将此文件作为模块,而不是其内容在全局范围内可用的脚本。有时,您会从第三方节点模块导入并使用一些接口或类型。但就你的情况而言,你不需要它。所以只需使用export {}or import 'express-session',两者都可以。

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}

export {};
Run Code Online (Sandbox Code Playgroud)

tsconfig.json:

import express from 'express';
import session from 'express-session';

const app = express();

app.use(
  session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true },
  }),
);
app.get('/', (req, res) => {
  const user = { id: '1' };
  req.session.userId = user.id;
});
Run Code Online (Sandbox Code Playgroud)

软件包版本:

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}

export {};
Run Code Online (Sandbox Code Playgroud)

  • 好吧,这似乎可行,但我对在 d.ts 上导入快速会话或导出空对象持怀疑态度。我实在是不太理解。节点中的所有文件不都被视为一个模块吗?为什么 d.ts 文件需要成为一个模块才能工作?我发现的所有示例和教科书都只是在没有这个的情况下进行合并。我只是担心这是打字稿黑客。 (3认同)