Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending session object in express-session

I know this is not an actual issue, but a help wanted.

I'm struggling with typescript and express session and I have been playing around and trying to fiugure out this one for quite a bit.

I'm trying to extend my session object, for that, I'm trying to do a merge of typings as per in the documentation:

I have a types/session.d.ts with the following interface to be merged:

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}

But this is not working, as an example, in other-folder/some.ts

req.session.userId = user.id;
// Property 'userId' does not exist on type 'Session & Partial<SessionData>'.

However, if I import Session from express-session, it does work:

import { Session } from 'express-session'

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}

I'm not very proficient with TypeScript and I'm unsure about importing a module in a type defintion, event TypeScript complains about this (warning):

'Session' is declared but its value is never read.

I'm wondering, is this the right way of tackling the problem?

What can I do different?

Kind regards!

PS: my tsconfig should be fine as I have available through my code other type definitions and they are working with no issues at all.

like image 785
avcajaraville Avatar asked Dec 01 '25 06:12

avcajaraville


1 Answers

You should use Module Augmentation. You should also know this from Modules:

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

For example:

./src/main.ts:

import express from 'express';
import session from 'express-session';

const app = express();

app.use(
  session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true },
  }),
);
app.get('/', (req, res) => {
  const user = { id: '1' };
  req.session.userId = user.id;
});

./types/session.d.ts: Make sure you include at least one top-level import or export to make this file as a module, NOT a script whose contents are available in the global scope. Sometimes, you will import and use some interfaces or types from third-party node modules. But in your case, you don't need it. So just use export {} or import 'express-session', both of them are ok.

declare module 'express-session' {
  interface SessionData {
    userId: string;
  }
}

export {};

tsconfig.json:

"typeRoots": [
  "./node_modules/@types",
  "./types",
], 

package versions:

"express": "^4.17.1",
"@types/express": "^4.17.11",
"typescript": "^3.9.7"
"express-session": "^1.17.1",
"@types/express-session": "^1.17.3",
like image 98
slideshowp2 Avatar answered Dec 04 '25 05:12

slideshowp2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!