Typescript Error: Property 'user' does not exist in type 'Request'
I have the following piece of code in my express application
router.get('/auth/userInfo', this.validateUser, (req, res) => {
res.json(req.user);
});
and my IDE seems to be complaining about the error
error TS2339: Property 'user' does not exist on type 'Request'.
When I compile the typescript code it seems to be throwing this error. Any idea why this is happening?
source to share
We have a large API written in Express and Typescript, and this is how we handle scripts like this:
We keep the request definitions in one file:
import { Request } from "express"
export interface IGetUserAuthInfoRequest extends Request {
user: string // or any other type
}
And then in the file where we write the controller functions:
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
});
Note that "user" is not a property that is natively available in the Express Request object. Make sure you are using middleware that adds such a property to the request object.
source to share
req is probably of type Request from the "express" package and the user does not exist there. You must either extend Request with your own router handler, or cast it to any or object.
try res.json(req['user'])
orres.json( (<any>req).user )
You can also use module / global increase
import { Request } from "express"
declare module "express" {
export interface Request {
user: any
}
}
You can also create your own handler wrapper (instead of extending Router functionality in 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);
}));
source to share
You are getting this error because there is no type definition for the property user
on its own object express Request
. You should set up type definitions for the middleware you use to add user
to the request.
For example, if you are using the passport
JWT authentication library as 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);}
...
...
You must add type definitions for passport
:
npm install --save @types/passport
source to share
Old question, but if someone stumbles upon this like me take a look at "Concatenating Declarations" - it solved the problem for me.
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
https://truetocode.com/extend-express-request-and-response-typescript-declaration-merging/
source to share