提问者:小点点

扩展护照用户参数的快速请求


我使用Passport来处理Express应用程序的身份验证。这将用户设置为快速响应。我正在使用TypeScript,因此在路由定义中将请求类型设置为request将会出错,因为用户对象不存在于Express请求中。关于扩展请求,无论是通过声明合并还是扩展接口,都有许多问题,但这会导致另一个错误。我的文件看起来像这样:

import { Router, Request, Response }  from 'express'
import { User as CustomUser } from './user'

interface IRequest extends Request {
  user: CustomUser
}

const router: Router = Router()

router.get('/', requiresLogin, (req: IRequest, res: Response) => {
  console.log(req.user)
  res.sendStatus(204)
})

但现在我在express回调中得到了以下TypeScript:

Argument of type '(req: IRequest, res: Response) => void' is not assignable to parameter of type 'RequestHandlerParams'. Type '(req: IRequest, res: Response) => void' is not assignable to type '(RequestHandler | ErrorRequestHandler)[]'. Property 'includes' is missing in type '(req: IRequest, res: Response) => void'.

我最近升级到了TypeScript v2.8.3,以前从未遇到过这个问题。


共1个答案

匿名用户

我刚刚遇到了一个类似的问题,是这样解决的:

import { Router, Request, Response } from 'express';
import { User as CustomUser } from './user';

const router: Router = Router();

router.get('/', requiresLogin, (req: Request, res: Response) => {
  console.log(req.user as CustomUser);
  res.sendStatus(204);
});

我没有增加 Express.js Request 类型,而是简单地告诉 TypeScript,req.user 将使用类型断言属于 CustomUser 类型。这似乎是文档中的引用“有时你最终会比 TypeScript 更了解值的情况”的确切场景。

https://www.typescriptlang.org/docs/handbook/basic-types.html#type-断言

现在我知道你在想什么了。“如果没有用户怎么办?这难道不违背打字稿的目的吗?好吧,让我们看看这个。如果您使用的是Passport.js,则在没有用户的情况下,您不应该走到这一步。此代码应该在您的护照配置中的某个位置:

if (!user) {
  /** Set status code to Unauthorized */
  res.status(401);

  return next(err);
}

至于击败Typescript……也许你是对的。不过,如果有人对这种情况有更好的答案,我洗耳恭听。