我使用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,以前从未遇到过这个问题。
我刚刚遇到了一个类似的问题,是这样解决的:
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……也许你是对的。不过,如果有人对这种情况有更好的答案,我洗耳恭听。