Enhancing the session object with new properties

I am attempting to include extra properties in the session object

req.session.confirmationCode = confirmationCode;

However, I encounter an error stating that the property confirmationCode does not exist

Property 'confirmationCode' does not exist on type 'Session & Partial<SessionData>'.

I have an index.d.ts file located in the types directory where I define this property

declare global {
  namespace session {
    interface SessionData {
      confirmationCode: number;
    }
  }
}

export {};

This is my tsconfig.json configuration file

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
    "sourceMap": true,
    "outDir": "./dist",
    "moduleResolution": "node",
    "removeComments": true,
    "strict": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "noImplicitAny": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noStrictGenericChecks": true
  },
  "exclude": ["node_modules"],
  "include": ["src"]
}

In the source code for @types/express-session package, I found out that I can extend the session object like so

declare module "express-session" {
  interface SessionData {
    confirmationCode: number;
  }
}

Yet, when I try this approach, I receive an error mentioning that the session function is not callable

Type 'typeof import("express-session")' has no call signatures

What is the correct way to properly extend the session object?

UPD1: Here is how I invoke the session function

app.use(
  session({
    name: "wishlify",
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 1000 * 60 * 60 * 24 * 60, // 2 months
      secure: process.env.NODE_ENV === "production",
    },
  })
);

Answer №1

I discovered a solution in the midst of this inquiry.

By inserting export {}; into the index.d.ts file, everything is now operating as intended.

This adjustment transforms the file from a script to a module.

The updated version of the index.d.ts file

declare module "express-session" {
  interface SessionData {
    confirmationCode: number;
  }
}

export {};

Answer №2

Upon delving into the depths of

node_modules > @types > express-session > index.d.ts
, I stumbled upon the definition for Session that caught my attention. (I've stripped away all the comments)

class Session {
  private constructor(request: Express.Request, data: SessionData);
  id: string;
  cookie: Cookie;
  regenerate(callback: (err: any) => void): this;
  destroy(callback: (err: any) => void): this;
  reload(callback: (err: any) => void): this;
    @see Cookie
  resetMaxAge(): this;
  save(callback?: (err: any) => void): this;
  touch(): this;
}

I took the liberty to include a new property in my session, namely userId.

Subsequently, the contents of my

node_modules > @types > express-session > index.d.ts
now appear as follows:

class Session {
  private constructor(request: Express.Request, data: SessionData);
  id: string;
  userId: number; // This addition is what sets it apart.
  cookie: Cookie;
  regenerate(callback: (err: any) => void): this;
  destroy(callback: (err: any) => void): this;
  reload(callback: (err: any) => void): this;
    @see Cookie
  resetMaxAge(): this;
  save(callback?: (err: any) => void): this;
  touch(): this;
}

While I can't guarantee that this approach is foolproof, it certainly served my purpose.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountered error message: "Cannot assign argument of type '() => () => boolean' to parameter of type 'EffectCallback'"

I recently started working with TypeScript. I encountered an issue when attempting to utilize useEffect in TypeScript within a React context, Error: Argument of type '() => () => boolean' is not assignable to parameter of type 'Effec ...

Angular version 12 (node:3224) UnhandledPromiseRejectionWarning: Issue encountered with mapping:

Trying to generate the translation file in my Angular project using the command ng extract-i18n --output-path src/translate, I encountered this error message: \ Generating browser application bundles (phase: building)...(node:3224) UnhandledPromiseRej ...

Tips on displaying hyperlinks within a text area in an Angular application

In my Angular application, I am facing an issue with displaying hyperlinks within a text area box for dynamic content. The hyperlinks are not recognized and therefore cannot be clicked. Can someone please advise on how to properly display hyperlinks with ...

How to specify the return type of a promise from an observer in Angular 6

Typically, I prefer using observables. However, in order to avoid 'callback hell' in this particular scenario, I decided to use toPromise(). Unfortunately, I encountered a lint error message when trying to define the return type: The 'Obj ...

Establishing a USERs database structure with Express

Hey there! I am diving into the world of Express and NodeJS, and I've got a beginner question. Background So, I followed a tutorial to create a REST API with Express and Passport for authentication. Currently, my setup provides basic authentication ...

Deciphering data sent through Twilio POST requests in NodeJS using Express

I am new to Node.js and I am currently trying to understand how to retrieve data from a POST request. Here is the code I have so far: var bodyParser=require("body-parser"); app.use(bodyParser.json()); app.post('/hello', function(req,res){ c ...

Applying CDNJS CSS or external CSS to Nodemailer HTML templates with Jade and Express: A Guide

I am attempting to send emails using node mailer. I have a jade template with HTML markup in an external file, which is compiled and rendered correctly. However, the styles inserted through maxcdn or cdnjs are not being applied. In this situation, how can ...

Presentation of information with loading and error scenarios

How can we effectively display data in an Angular view, considering loading state and error handling? Imagine we are fetching a set of documents from our backend and need to present them in an Angular view. We want to address three possible scenarios by p ...

Issue: Interface not properly implemented by the service

I have created an interface for my angular service implementation. One of the methods in the service returns an observable array, and I am trying to define that signature in the interface. Here's what I have so far: import {Observable} from 'rxj ...

Combining TypeScript with Vue3 to implement bootstrapVue

After using BootstrapVue as any, the error was corrected but unfortunately it still doesn't work in the browser. Here is what's inside main.ts: import { createApp }from 'vue'; import App from './App.vue'; import router from & ...

Node and the power of modular programming

UPDATE 1: After making significant progress on this project, I have decided to focus on developing a structure for defining and loading multiple modules, rather than allowing user-uploaded modules. Each module will have its own routes and a 'public&ap ...

Angular and Express: Automatically redirecting to the previous page after user login

A question similar in nature can be found here, although not directly relevant to my situation. Within my Single Page Application, I am implementing PassportJS for user authentication. There are multiple routes that necessitate user login. The routing is ...

using outlines for FontAwesome icons in React Native

I am struggling to use the fontAwesome + icon in the middle of a circle as one item. I have tried placing it inside a circle icon, but it doesn't seem to work properly. import IconFA from 'react-native-vector-icons/FontAwesome'; < ...

Numerous toggle classes available

Having the following HTML inside a <span> element: <span (click)="openLeft()"></span> A method in a @Component sets a boolean variable like so: private isOpen: boolean; openLeft() { this.isOpen = !this.isOpen; } To toggle classes ...

Extending Record in Typescript: A Comprehensive Guide

When working on interfaces, I often find myself wanting to extend the type Record in order to define objects with predefined keys and optional values without knowing their names. For instance: interface Person extends Record<string, string>{ phonen ...

The optimal time to register for events within the Vue lifecycle

Currently, I am developing a Vue2 component using vue-component that includes a subcomponent. Here is an example: <note :bus="bus" :itemId="selectedId"></note> The subcomponent contains the following code snippet: <textarea v-model="text" ...

Guidelines for crafting an intricate selector by utilizing mergeStyleSets and referencing a specific class

I'm currently in the process of developing a web application using ReactJS. In my project, I have the following code: const MyComponent = (props: { array: Array<Data> }) => { const styles = mergeStyleSets({ container: { ...

Utilize esbuild to monitor for any modifications, recompile the code, and automatically restart the express server

In my endeavor to develop a basic SSR-powered project using express + react, I find the need to monitor frontend and backend scripts concurrently in the development process. The primary objective is to utilize express routes in directing to react page com ...

Comparing TypeScript and C++ in terms of defining class reference member variables

class B; class A { A(B b_) : b{b_} {} B &b; }; In C++, it is possible to have a reference member variable like 'b' in class A. Can the same be achieved in TypeScript? Alternatively, is there a specific method to accomplish this in ...

Personalized ornamentation using TypeScript

Is there a way to access the variables of the class when using a decorator? @ExampleDecorator() export class UserController { private userData: string = "example"; } export const ExampleDecorator = (config: IConfigSettings) => (target: Object) =&g ...