Impossible d'étendre la demande expresse
J'essaie d'étendre l' Requestinterface de Expressas:
import express, { Request, Response } from 'express';
interface IRequest extends Request {
user: {
id: string;
}
}
const router = express.Router();
router.get('/', auth, async (req: IRequest, res: Response) => {
try {
const user = await User.findById(req.user.id).select('-password');
res.json(user);
} catch (e) {
console.error((e as Error).message);
res.status(500).send('Server Error');
}
});
mais j'ai l'erreur suivante :
Aucune surcharge ne correspond à cet appel. La surcharge 1 sur 3, '(path: PathParams, ...handlers: RequestHandler<ParamsDictionary, any, any, ParsedQs>[]): Router', a donné l'erreur suivante. L'argument de type '(req : IRequest, res : Response) => Promise' n'est pas assignable au paramètre de type 'RequestHandler<ParamsDictionary, any, any, ParsedQs>'. Les types de paramètres 'req' et 'req' sont incompatibles. La propriété 'user' est manquante dans le type 'Request<ParamsDictionary, any, any, ParsedQs>' mais requise dans le type 'IRequest'. La surcharge 2 sur 3, '(path: PathParams, ...handlers: RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>[]): Router', a donné l'erreur suivante. Argument de type '(req : IRequest, res : Response) => Promise' n'est pas assignable au paramètre de type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>'. Le type '(req : IRequest, res : Response) => Promise' n'est pas attribuable au type 'RequestHandler<ParamsDictionary, any, any, ParsedQs>'.ts(2769)
Réponses
Typescript ne vous laissera pas faire, car même si vous l'avez tapé de cette façon :
router.get('/', auth, async (req: IRequest, res: Response) => {
Typescript supposera toujours qu'express émettra un Requestet non un IRequest.
Cependant, puisque vous êtes probablement en train de patcher l'objet de requête, vous pouvez utiliser la fusion de déclaration pour essentiellement augmenter l'objet de requête interne d'Express :
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
Si vous ne souhaitez pas apporter cette modification globalement à Request, vous pouvez également utiliser une assertion pour vous assurer qu'il s'agissait bien d'un IRequest:
router.get('/', auth, async (req: request, res: Response) => {
try {
assertIRequest(req);
const user = await User.findById(req.user.id).select('-password');
res.json(user);
} catch (e) {
console.error((e as Error).message);
res.status(500).send('Server Error');
}
});
function assertIRequest(req: Request|IRequest): asserts req is IRequest {
if (!req?.user?.id) throw new Error('Request was not an IRequest');
}