You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中扩展Express Request接口以添加Mongoose Session?

解决Express Request扩展Mongoose Session的TypeScript错误

问题复盘

在Express+Mongoose+TypeScript项目中,尝试给Request对象附加Mongoose事务Session时,TS报错Property 'session' does not exist on type 'Request',即使已添加自定义类型声明并修改tsconfig.json,问题仍未解决。

可能的原因及解决方案

1. 类型声明文件未被识别为模块

自定义类型声明文件需要被TS识别为模块,否则全局扩展不会生效。修改types/express.d.ts:

import { Session } from 'mongoose';

declare global {
  namespace Express {
    interface Request {
      // 改用明确命名避免和express-session的内置session属性冲突
      mongooseSession?: Session;
    }
  }
}

// 必须添加此行,让TS将文件视为模块
export {};

2. 完善tsconfig.json配置

仅设置typeRoots不足够,需确保TS能扫描到自定义类型目录并启用必要编译选项:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "typeRoots": ["./node_modules/@types", "./types"],
    // 显式包含源码和类型文件
    "include": ["src/**/*", "types/**/*"],
    "exclude": ["node_modules"]
  }
}

3. 更新中间件代码

使用扩展后的属性名,确保TS识别新增属性:

import { Request, Response, NextFunction } from 'express';
import mongoose from 'mongoose';

const sessionMiddleware = async (req: Request, res: Response, next: NextFunction) => {
  const session = await mongoose.startSession();
  session.startTransaction();
  
  // 赋值扩展的属性
  req.mongooseSession = session;

  res.on('finish', async () => {
    try {
      if (res.statusCode >= 200 && res.statusCode < 400) {
        await session.commitTransaction();
      } else {
        await session.abortTransaction();
      }
    } catch (err) {
      // 捕获事务错误,避免连接泄漏
      await session.abortTransaction();
      console.error('Transaction error:', err);
    } finally {
      session.endSession();
    }
  });
  
  next();
};

export default sessionMiddleware;

4. 强制刷新TS服务器

如果使用VS Code等编辑器,按Ctrl+Shift+P(Windows/Linux)或Cmd+Shift+P(Mac),选择TypeScript: Restart TS Server,确保TS重新加载类型声明。

额外注意事项

  • 避免使用session作为属性名:express-session库也会给Request添加同名属性,易引发类型冲突,建议用mongooseSession这类明确命名。
  • 事务错误处理:在finish事件中添加try/catch,防止事务操作失败导致Session无法正常关闭,引发数据库连接泄漏。

内容的提问来源于stack exchange,提问作者Roni Jack Vituli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:05:11