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

访问req.user.id时出现TypeScript错误的排查求助

解决Passport认证后req.user.id的TypeScript类型错误

问题根源

  1. Express默认的Request接口未定义带有id属性的user字段,TypeScript无法识别req.user的具体类型
  2. MongoDB Employee模型返回的文档主键是_id而非id,代码中直接访问req.user.id本身存在逻辑错误

解决方案

步骤1:扩展Express Request类型

在项目src/typings目录下创建express.d.ts文件(目录不存在则新建),用于扩展Express的类型定义:

import { Request } from 'express';
import Employee from '../models/employee.model';

// 扩展Express的Request接口,添加自定义user类型
declare module 'express' {
  interface Request {
    // 若user可能不存在,可改为 Employee | undefined
    user: Employee;
  }
}

步骤2:修正req.user的属性访问(二选一)

选项A:直接使用MongoDB原生_id字段

修改employee.controller.ts中的代码:

import { Request, Response } from 'express';
import responseSuccess from './path-to-your-responseSuccess'; // 确保导入该函数

export const createEmployee = async (req: Request, res: Response) => {
    // 使用MongoDB原生的_id字段
    const currentUser = req.user._id;
    return responseSuccess(res, { newUser: req.body, user: currentUser });
};

选项B:在Passport回调中转换为id字段

如果希望统一使用id而非_id,修改passport.ts中的JWT策略回调:

passport.use(
  new JwtStrategy(opts, async (jwtPayload, cb) => {
    const employee = await Employee.findOne({ _id: jwtPayload.id }).select('-password -otpSecret').exec();
   
    if (employee) {
      // 将MongoDB的_id转换为id,同时转为普通对象避免Mongoose文档类型问题
      const user = { ...employee.toObject(), id: employee._id };
      cb(null, user);
    } else {
      cb(new Error("Something wrong in token"), false);
    }
  })
);

同时更新express.d.ts的类型定义(建议定义自定义User接口):

import { Request } from 'express';

// 定义自定义User类型
interface User {
  id: string;
  email: string;
  // 添加Employee模型的其他字段
}

declare module 'express' {
  interface Request {
    user: User;
  }
}

步骤3:完善中间件的类型标注

修改Authentication.ts,添加正确的类型标注:

import passport from "passport";
import { Request, Response, NextFunction } from 'express';
import UnauthorizedError from "../common/http-errors/UnauthorizedError";
import InternalServerError from "../common/http-errors/InternalServerError";
import messages from "../common/messages";

export default async (req: Request, res: Response, next: NextFunction) => {
  passport.authenticate("jwt", {}, (error, user, info) => {
    if (error) {
      return next(new InternalServerError());
    }

    if (user) {
      req.user = user;
      return next();
    }
    return next(new UnauthorizedError(messages.auth.invalidToken));
  })(req, res, next);
};

步骤4:调整tsconfig.json确保类型文件被识别

修改tsconfig.json的include字段,确保自定义类型文件被编译:

{
  "files": ["src/index.ts", "config/env.ts"],
  "compilerOptions": {
      // 保留现有配置
  },
  "include": ["src/**/*.ts", "src/typings/**/*.ts"]
}

完成以上步骤后,TypeScript就能正确识别req.user的类型,同时解决属性不存在的错误。

内容的提问来源于stack exchange,提问作者Raymond

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:22:10