首页 > 解决方案 > 在快速会话中扩展会话对象

问题描述

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

我正在为打字稿和快速会话而苦苦挣扎,我一直在玩弄并试图弄清楚这个问题。

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

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

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

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

req.session.userId = user.id;
// Property 'userId' does not exist on type 'Session & Partial<SessionData>'.

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

import { Session } from 'express-session'

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

我对 TypeScript 不是很精通,我不确定在类型定义中导入模块,事件 TypeScript 抱怨这个(警告):

'Session' 已声明,但它的值从未被读取。

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

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

亲切的问候!

PS:我的 tsconfig 应该没问题,因为我可以通过我的代码获得其他类型定义,并且它们完全没有问题。

标签: typescriptexpressexpress-session

解决方案


您应该使用Module Augmentation。您还应该从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;
});

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

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

export {};

tsconfig.json

"typeRoots": [
  "./node_modules/@types",
  "./types",
], 

包版本:

"express": "^4.17.1",
"@types/express": "^4.17.11",
"typescript": "^3.9.7"
"express-session": "^1.17.1",
"@types/express-session": "^1.17.3",

推荐阅读