Typescript Error: Property 'user' does not exist on type 'Request'

typescript custom error
javascript error message
javascript custom error
javascript extend error
extends javascript error
javascript wrap error
nodejs extend error
custom error types js

I have the following piece of code in my express app

router.get('/auth/userInfo', this.validateUser,  (req, res) => {
    res.json(req.user);
});

and my IDE seems to be complaining with the error

error TS2339: Property 'user' does not exist on type 'Request'.

When I compile my typescript code it seems to be throwing this error. Any ideas why this is happening?

We have a large API written in Express and Typescript, and this is how we handle such scenarios:

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 are writing 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
});

Be advised that "user" is not a property that is available natively in the Request object of Express. Make sure that you are using a middleware that adds such property to the request object.

TypeScript 2.2 · TypeScript, Constructs a type with all properties of T set to optional. { title: 'Delete inactive users', }; todo.title = 'Hello'; // Error: cannot reassign a readonly property. When compiled/transpiled through TypeScript it generates error TS2339: Property 'myclassvar' does not exist on type 'MyClass'. If the above code snippet is valid ES6 then TypeScript should not generate the error. The generated javascript it valid. It's just that the error scares the developers trying to use ES6 without typings.

req is probably of type Request from "express" package and user does not exist there. You have to either extend Request with own router handler or cast it to type any or object.

try res.json(req['user']) or res.json( (<any>req).user )

You may also use module/global augmentation

import { Request } from "express"

declare module "express" { 
  export interface Request {
    user: any
  }
}

You can also make 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);
}));

Utility Types · TypeScript, When compiled/transpiled through TypeScript it generates error TS2339: Property 'myclassvar' does not exist on type 'MyClass'. If the above  In TypeScript 2.0, the readonly modifier was added to the language. Properties marked with readonly can only be assigned to during initialization or from within a constructor of the same class. All other assignments are disallowed.

You're getting this error because there's no type definition for the user property in the the native express Request object. You should install the type definitions for the middleware you're using to add user to the request.

For example, if you're using the passport library for JWT authentication 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 should add the type definitions for passport:

npm install --save @types/passport

Getting error TS2339: Property does not exist on type for a valid ES6 , Why does declare const window: any; ? Because you declare a local variable of type any . Having something of type any essentially turns off  TypeScript supports getters/setters as a way of intercepting accesses to a member of an object. This gives you a way of having finer-grained control over how a member is accessed on each object. Let’s convert a simple class to use get and set. First, let’s start with an example without getters and setters.

Old question but if anyone stumbles across this like I did, take a look at 'Declaration Merging' - solved the issue for me.

https://www.typescriptlang.org/docs/handbook/declaration-merging.html

https://truetocode.com/extend-express-request-and-response-typescript-declaration-merging/

TypeScript error: Property 'X' does not exist on type 'Window', Error:(54, 6) TS2339:Property 'name' does not exist on type '{}'. So what is going here? We have defined an empty object first and then tried to  TypeScript Private Properties. Using TypeScript, we can add private functionality into our classes. What are private properties or methods? A private property of method can only be accessed or called from the class instance itself. Let’s take a look at an example private property.

Typescript 2 Type System: How Does it Really Work? Type , toUppercase(); // ~~~~~~~~~~~ // error: Property 'toUppercase' does not exist on type 'string'. // Did you mean 'toUpperCase  Ultimately the goal of TypeScript is to type existing JavaScript constructs in the least disruptive way. For that reason, TypeScript 3.7 introduces a new concept called “assertion signatures” which model these assertion functions. The first type of assertion signature models the way that Node’s assert function works. It ensures that whatever condition is being checked must be true for the remainder of the containing scope.

Announcing TypeScript 3.7, Especially with optional properties, you thought errors beginning with Object literal may only specify known properties were a thing of the past. When it comes to properties, TypeScript’s private modifiers are fully erased - that means that at runtime, it acts entirely like a normal property and there’s no way to tell that it was declared with a private modifier.

Common TypeScript Error Messages, Now, let us start with the very basics of TypeScript as a superset of JavaScript “​T” function getAsync(arg: T): Promise { // ERROR: Property 'id' does not exist on  TypeScript Virtual Projects D:\Email Test Application\EmailBuilder\TypeScriptHTMLApp5\app.ts 85 Active TS2488 Type must have a '[Symbol.iterator]()' method that returns an iterator. TypeScript Virtual Projects Dec 7, 2016

Comments
  • probably because of missing type on req - fast fix (req: any, res: any) => ... otherwise you might need to use some type info for express
  • this is also a way to trick typescript and it isn't guaranteed to have a user object as @MadaraUchiha pointed out (...and downvoted me for :-P ). It would be better to have build a specialized router that does all of this.
  • Thanks for your answer :)
  • This is giving me Argument of type '(req: ExtendedRequest, res: Response) => Promise<void>' is not assignable to parameter of type 'Application'. Type '(req: ExtendedRequest, res: Response) => Promise<void>' is missing the following properties from type 'Application': init, defaultConfiguration, engine, set, and 62 more.
  • Depending on the implementation of the authorization middleware, it is guaranteed that a user property is part of the req object for all routes that require the user to be authorized, so it shouldn't be a huge problem in most cases. It doesn't solve the underlying problem though, that is correct.
  • @roxxypoxxy I assume you are trying to implement this firebase middleware? github.com/firebase/functions-samples/blob/master/… In practice express can handle async middleware just fine, the express types are too limited in this regard. The real solution would be to write types from scratch to account for req.user and the fact that app.use can handle promises. A quick solution would be: app.use(validateFirebaseIdToken as any). This doesn't compromise on type safety in any way, though it isn't an optimal solution.
  • While these are valid workarounds, they do nothing to solve the underlying problem which TypeScript helpfully points out: It isn't guaranteed that request has a user property.
  • @MadaraUchiha I totally agree, thought first about extending Router but that is a bit of work. To make it simple you may use a handler wrapper instead. I edit my answer to include one example.
  • Can you explain the module/global augmentation method? I don't know how to set it up with TS 2.5 (and express types installed on @types/express)
  • @BrunoLM try declare module "express-serve-static-core" instead, but it is a lot better to use a request handler instead.
  • How do you import the passport Request interface?
  • @Kriss just installing the types as duliba described it should be enough for your type checker to augment express' Request interface. For more information, have a look at the typings file: github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/…
  • This is a very quick fix. Thanks. Worked for me.