打字稿:req.user 可能是 'undefined' - 快递和护照 js

typescript: req.user is possibly 'undefined' - express and passport js

我有一个使用护照的 Nodejs typescript 身份验证系统。

我的问题是,当我在路线中使用 req.user 时,我在 req.user 上收到此错误:Object is possibly 'undefined'.

这是 Typescript 的正常行为,但我正在使用中间件来保护我想在其中使用 req.user 的路由,这样 req.user 就不能未定义。

这是我扩展的地方Express.User类型:

import { users } from "@prisma/client";

declare global {
    namespace Express {
        interface User extends users {}
    }
}

这是我用来保护登录用户路由的中间件:

export function checkIsAuthenticated(req: Request, res: Response, next: NextFunction) {
    if (req.isAuthenticated()) {
        if (!req.user) req.logOut();
        else return next();
    }
    res.status(400).json({
        errors: [{ message: "no user logged in" }],
    });
}

这是获取用户信息的路径:

export function userRoute(req: Request, res: Response) { // defining the route
    res.json({
        id: req.user.id,               // I'm getting the error in these 4 lines
        username: req.user.username,   //
        email: req.user.email,         //
        role: req.user.role,           //
    });
}

router.get("/user", checkIsAuthenticated, userRoute); // using the route

我不想检查用户是否已定义,因为我不想在每条路线上都这样做,这不是一个好习惯。这就是中间件用于的原因。

我不擅长 Typescript,所以我需要一些帮助来修复它。 谢谢

export function userRoute(req: Request, res: Response) { // defining the route
    res.json({
        id: req.user!.id,               // you tell typescript that req.user for sure not. null
        username: req.user!.username,   //
        email: req.user!.email,         //
        role: req.user!.role,           //
    });
}

router.get("/user", checkIsAuthenticated, userRoute);

I don't want to check if user is defined because I don't want to do it in every route and that's not a good practice.

我尝试满足该要求的第一个解决方案没有奏效,因此我将其删除。我留下了我的第二个解决方案,即:

但是,我怀疑如果您不小心使用了这些处理程序之一,检查用户请求并给自己一个有用的错误消息并没有错在您忘记进行身份验证的路线上。看起来像这样:

type RequestWithUser = Request & {user: typeOfUserObject};
function assertHasUser(req: Request): asserts req is RequestWithUser {
    if (!( "user" in req)) {
        throw new Error("Request object without user found unexpectedly");
    }
}

然后是这些路由的处理程序:

export function userRoute(req: Request, res: Response) {
    assertHasUser(req);
    // ...you can use `req.user` here...
});

Playground example

(你真的不需要明确的 RequestWithUser 类型,你可以只使用 asserts req is Request & {user: typeOfUserObject}。)