Search code examples
node.jstypescriptexpressexpress-session

Typescript declare a new property in a existing library


i'm relative new to Typescript and i'm trying to declare a property in the req.session object from express-session.

I tried this, but it keeps giving me error that "req" is not compatible with "req" ?!?

The full error:

No overload matches this call.
  Overload 1 of 3, '(path: PathParams, ...handlers: RequestHandler<ParamsDictionary, any, any, ParsedQs>[]): Router', gave the following error.
    Argument of type '(req: Request<ParamsDictionary, any, any, ParsedQs>, res: Response<any>) => void' is not assignable to parameter of type 'RequestHandler<ParamsDictionary, any, any, ParsedQs>'.
      Types of parameters 'req' and 'req' are incompatible.
        Type 'import("/home/arvore/Documents/arvore/api/node_modules/@types/express-serve-static-core/index").Request<import("/home/arvore/Documents/arvore/api/node_modules/@types/express-serve-static-core/index").ParamsDictionary, any, any, qs.ParsedQs>' is not assignable to type 'import("/home/arvore/Documents/arvore/api/node_modules/@types/express/index").Request<import("/home/arvore/Documents/arvore/api/node_modules/@types/express-serve-static-core/index").ParamsDictionary, any, any, qs.ParsedQs>'.
          Types of property 'session' are incompatible.
            Property 'user' is missing in type 'Session & Partial<SessionData>' but required in type 'sessionData'.
  Overload 2 of 3, '(path: PathParams, ...handlers: RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>[]): Router', gave the following error.
    Argument of type '(req: Request<ParamsDictionary, any, any, ParsedQs>, res: Response<any>) => void' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs>'.
      Type '(req: Request<ParamsDictionary, any, any, ParsedQs>, res: Response<any>) => void' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs>'.
  Overload 3 of 3, '(path: PathParams, subApplication: Application): Router', gave the following error.
    Argument of type '(req: Request<ParamsDictionary, any, any, ParsedQs>, res: Response<any>) => void' is not assignable to parameter of type 'Application'.
      Type '(req: Request<ParamsDictionary, any, any, ParsedQs>, res: Response<any>) => void' is missing the following properties from type 'Application': init, defaultConfiguration, engine, set, and 61 more.
import { Session, SessionData } from "express-session";

interface userInformation {
    username: string,
    email: string,
}

interface sessionData extends Session {
    user: userInformation
}

declare module "express" {
    interface Request {
        session: sessionData
    }
}

Edit:

The controller that i'm using:

import { Request, Response } from "express";


class AppAPIController {
    public getUserByAuth(req: Request, res: Response) {
        return res.json(req.session.user)
    }
}

export default new AppAPIController;

My routes file:

import { Router } from "express";
import AppAPIController from "./controllers/AppAPIController";

const routes = Router();

routes.get("/@me", AppAPIController.getUserByAuth);

Solution

  • You want to extend a user property as session data on req.session object, you need to extend SessionData interface:

    import express, { Request, Response, Router } from 'express';
    import session from 'express-session';
    
    const app = express();
    const routes = Router();
    
    interface userInformation {
      username: string;
      email: string;
    }
    
    declare module 'express-session' {
      interface SessionData {
        user: userInformation;
      }
    }
    class AppAPIController {
      public getUserByAuth(req: Request, res: Response) {
        return res.json(req.session.user);
      }
    }
    
    const controller = new AppAPIController();
    
    app.use(
      session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: true,
        cookie: { secure: true },
      }),
    );
    routes.get('/@me', controller.getUserByAuth);
    
    

    package versions:

    "express": "^4.17.1",
    "express-session": "^1.17.1",
    "@types/express-session": "^1.17.3",
    "@types/express": "^4.17.11",
    "typescript": "^3.9.7"
    

    result:

    enter image description here