访问req.user.id时出现TypeScript错误的排查求助
解决Passport认证后req.user.id的TypeScript类型错误
问题根源
- Express默认的
Request接口未定义带有id属性的user字段,TypeScript无法识别req.user的具体类型 - 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
相关产品推荐
相关产品推荐

