Search code examples
expresstypescript-typingsexpress-session

Argument of type 'Session | undefined' is not assignable to parameter of type 'Session'


Here's a simplified version of my code:

npm install express express-cookies @types/cookie-session @types/express-session
import express from express();
import cookieSession from 'cookie-session';


const app = express();

app.use(cookieSession({
    name: 'session',
    keys: [
        process.env.SESSION_KEY as string
    ]
}));

const router = express.Router();

const changeSession = (session = express.Session) => {
    session.foo = 'bar'
}

router.get((req, res) => {
    changeSession(req.session)
});

On changeSession(req.session) I get the error:

Argument of type 'Session | undefined' is not assignable to parameter of type 'Session'.
  Type 'undefined' is not assignable to type  'Session'

Same happens when I use app.get instead of router.get

Not sure why express-cookies isn't registering the session object to the request properly.

Here's a link to @types/cookie-session: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/cookie-session/index.d.ts which provides typings for express-cookies

Any help?


Solution

  • The express-cookies typings specify that req.session can be undefined. As I understand, req.session will be defined only if you register the cookieSession middleware with express. So, if for any reason you won't register this middleware (e.g., delete the code which registers it by mistake), req.session will be undefined.

    Because there is a possibility that the session middleware may not be registered, type-wise it is correct to expect that req.session may be undefined.

    So, using TS you would need to check if req.session is defined before working with it:

    if (req.session) {
        changeSession(req.session)
    }
    

    Or throw an error explicitly if the session is mandatory for a route:

    if (!req.session) {
        throw new Error('Session is missing.');
    }
    
    changeSession(req.session)
    

    Or as last resort, use the exclamation mark to tell TS that req.session is actually defined:

    changeSession(req.session!)
    

    But this won't be type-safe.