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.
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",