J'ai le morceau de code suivant dans mon application express
router.get('/auth/userInfo', this.validateUser, (req, res) => {
res.json(req.user);
});
et mon IDE semble se plaindre de l'erreur
erreur TS2339: la propriété "utilisateur" n'existe pas sur le type "demande".
Lorsque je compile mon code TypeScript, il semble générer cette erreur. Des idées pourquoi cela se produit?
Nous avons une grande API écrite en Express et TypeScript, et voici comment nous traitons de tels scénarios:
Nous conservons les définitions de demande dans un seul fichier:
import { Request } from "express"
export interface IGetUserAuthInfoRequest extends Request {
user: string // or any other type
}
Et puis dans le fichier où nous écrivons les fonctions du contrôleur:
import { Response } from "express"
import { IGetUserAuthInfoRequest } from "./definitionfile"
app.get('/auth/userInfo', validateUser, (req: IGetUserAuthInfoRequest, res: Response) => {
res.status(200).json(req.user); // Start calling status function to be compliant with Express 5.0
});
Sachez que "utilisateur" n'est pas une propriété disponible en mode natif dans l'objet Request d'Express. Assurez-vous que vous utilisez un middleware qui ajoute une telle propriété à l'objet de demande.
Vous obtenez cette erreur car il n'y a pas de définition de type pour la propriété user
dans l'objet natif express Request
. Vous devez installer les définitions de type pour le middleware que vous utilisez pour ajouter user
à la demande.
Par exemple, si vous utilisez la bibliothèque passport
pour l'authentification JWT comme middleware:
router.get('/auth/userInfo', passport.authenticate('jwt', {session:false}), (req, res, next) => {
// Get their info from the DB and return it
User.findOne({ email: req.user.email }, (err, user) => {
if (err) {return next(err);}
...
...
Vous devez ajouter les définitions de type pour passport
:
npm install --save @types/passport
req est probablement de type Request from "express" package et user n'existe pas là-bas. Vous devez soit étendre Request avec son propre gestionnaire de routeur, soit le convertir en type any ou object.
essayez res.json(req['user'])
ou res.json( (<any>req).user )
Vous pouvez également utiliser le module/l'augmentation globale
declare module "express" { // declare module "express-serve-static-core"
export interface Request {
user: any
}
}
Vous pouvez également créer votre propre wrapper de gestionnaire (au lieu d'étendre les fonctionnalités du routeur dans ExpressJs).
import * as express from 'express';
interface IUserRequest extends express.Request {
user: any
}
function myHandler(handler: (req: IUserRequest, res: express.Response, next?: express.NextFunction) => any) {
return (req: express.Request, res: express.Response, next: express.NextFunction) => {
try {
validateUser(req, res, (err) => { // your validateUser handler that makes a user property in express Request
if(err)
throw err;
let requestWrapper: IUserRequest = <IUserRequest>req;
handler(requestWrapper, res, next);
})
}
catch (ex) {
next(ex);
}
}
}
let app = express();
// init stuff for express but this.validateUser handler is not needed
app.use('/testuser', myHandler((req, res) => {
res.json(req.user);
}));