Express: custom middleware specific to the project that enhances the Express.Request object

Currently, I am in the process of developing a node server using Express and TypeScript 1.7. The middleware I am working with is tailored to my project and extends the existing express Request or Response interface. However, I am encountering issues as TypeScript keeps complaining about not finding certain elements in req or res. I have come across some discussions on this topic but haven't found a clear-cut solution yet.

I've examined the definition of an already existing middleware, but integrating it without having to manually create separate d.ts files and reference them in typings/tsd.d.ts has been a challenge. Here is how my setup looks like:

// middleware/foobar.ts
declare module Express {
  export interface Request {
    foobar?: string;
  }
}

/* My custom middleware for the project appends 'foobar' to the request */
export = function(req: Express.Request, res, next) {
  req.foobar = 'FooBar';
  next();
};

// main.ts
import express = require('express');

var app = express();

app.use(require('./middleware/foobar'));

app.get('/foobar', (req, res) => {
  /* TypeScript error: Property 'foobar' does not exist on type 'Request' */
  res.send(req.foobar);
});

Any suggestions on the best approach to extend express' Request and Response interfaces? Ideally, I would like to achieve this without the need for separate d.ts files, modifying anything within the typings directory, or utilizing

/// <reference path="..." />
comments.

Answer №1

After some exploration, I managed to come up with a solution on my own by making use of this particular example as a guide. To ensure proper functionality, I found that my middleware needed to be enclosed within a declared module framework. Therefore, the file for my middleware (foobar.ts) takes on this structure:

declare module Express {
  export interface Request {
    foobar?: string;
  }
}

declare module 'foobar' {
  function foobar(req: Express.Request, res, next) {
    req.foobar = 'FooBar';
    next();
  }

  export = foobar;
}

Things got even more intricate when dealing with classes or other imported elements in the middleware. In my scenario, my middleware relies on my custom "EntityManager" class, which acts as an abstraction layer for database connections (in my case, mysql). Consequently, the revised version of my middleware (located in middleware/database.ts) now appears like this:

declare module Express {
  import { Manager as EntityManager } from 'entity-manager';

  export interface Request {
    entityManager?: EntityManager;
  }
}

declare module 'database' {
  import * as mysql from 'mysql';
  import { Manager as EntityManager } from 'entity-manager';

  /* additional code pertaining to middleware */
  var pool = mysql.createPool(...);
  var entityManager = new EntityManager(pool);
  /* *** */

  /* primary exported function */
  function database(req: Express.Request, res, next) {
    req.entityManager = entityManager;
    next();
  };

  export = database;
}

It's worth noting that I had to import my EntityManager class twice, once in each module declaration. Simply importing it above both declarations did not yield the desired outcome.

UPDATE

Placing the actual code within a declared module ('database' in my instance) resulted in no output in the JS file.

Having the code within a standard module required omitting the name in apostrophes (i.e., hyphens would not be acceptable there) and did not generate a one-function-export code either.

When the code was completely outside of a module (leaving only the declared Express module with the extended Request), correct JS was produced; however, my text editor could no longer locate 'entityManager' in req.

It appears that I must segregate typings (such as my own expansions to Express.Request) into a dedicated d.ts file where actual code does not exist.

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

Angular's error notification system seems to be lacking in providing accurate

I'm experiencing an issue with my angular app where errors are not displayed properly. Instead of showing errors in the component and line number, they always appear in main.js. This is different from how errors are displayed in my other angular appli ...

The TypeScript/Webpack build for the Backend API server encountered an error: Module not found - Error: Unable to resolve

I am encountering a series of errors while trying to build my TypeScript application. I suspect that they are related to Webpack, but I am struggling to find a solution... ERROR in ./~/errorhandler/index.js Module not found: Error: Can't resolve &apo ...

Tips for creating an output directory when the TypeScript files are stored in the './src' location

Here is what I currently have: ./src/myfile.ts ./test/mytest.spec.ts I want tsc to output a javascript file (myfile.js) and a definition file (myfile.d.ts) in the ./build directory. This is my tsconfig.ts: { "compilerOptions": { "module": "common ...

express middleware failure to be triggered

Recently, I started working with node.js and have implemented express-validator as middleware to validate my POST data in requests. However, I encountered an error: (function(){ var express = require("express"); var expressValidator = require('ex ...

The Nestje subscription is encountering a NULL value and displaying an error message stating: "Non-nullable field Subscription cannot be returned as null."

I attempted to implement a Subscription in my nestjs project with GraphQL, but encountered the following error message: Cannot return null for non-nullable field Subscription Below is the code snippet: //* ~~~~~~~~~~~~~~~~~~~ Subscription ~~~~~~~~~~~ ...

What are the available events offered by Express websockets?

I am interested in learning about the different websocket events available. Currently, I have only used the ws.on('message') event, but I would like to find out how to detect when the connection is established and closed. I attempted to add the w ...

Modify the selection in one dropdown menu based on the selection in another dropdown menu using Angular 8

When I have two dropdowns, I aim to update the second dropdown with a matching JSON object based on the value selected in the first dropdown. JSON this.dropdownValues = { "mysql 8": { "flavor": [ "medium", ...

Using a REST API to make a POST request that calls a function and passes

Within my index.js file, the following code is implemented: app.post("/token", function (req, res) { var token = req.body createToken(token); }); This functionality is then exported by token.js const createToken = (token) = (req, res) => ...

Error encountered in Angular Html2Pdf: Unable to assign the 'adoptedStyleSheets' attribute on 'ShadowRoot' due to DOMException

Looking for assistance in implementing html2pdf with Angular 12 to convert specific parts of an HTML page into a downloadable PDF. ERROR MESSAGE An error occurred while trying to execute the code: index-7a8b7a1c.js:150 Uncaught (in promise) DOMExce ...

Every time my Canvas loads, it consistently fills up the entire width but neglects to occupy the complete height

My Canvas is only taking full width, but not full height. Here's my code snippet in an attempt to make it both full width and full height: export class AimComponent implements OnInit { @ViewChild('canvas') myCanvas: ElementRef; public ...

Retrieve a specific subdirectory from the bundle

I've developed a Typescript package with the following file structure: package.json src/ index.ts common/ index.ts sub/ index.ts My goal is to import certain modules from the package like this: import {...} from '<package>&ap ...

Adjust the tsconfig in Typescript to only output files to one specified folder, excluding the other folder from

Currently, I am in the process of converting a JavaScript project to TypeScript. My goal is to set noEmit = true for one folder while keeping noEmit = false for another folder. The reason behind this is that my client-side (Angular) code is configured thr ...

What is the correct way to include a new property in the MUI Link component using TypeScript?

Currently, within my mui-theme.ts configuration file, I have the following setup: const theme = createTheme(globalTheme, { components: { MuiLink: { variants: [ { props: { hover: 'lightup' }, style: { ...

Tips on displaying substitute text in Angular when an Iframe fails to load the content located at the src

Currently, I am working on an Angular 12 application and have a requirement to fetch content from an external site and display it within a modal popup. To achieve this, I am using the <iframe src="url"> tag to retrieve the content from a se ...

Check the validity of a password using Angular's reactive forms

For my password validation using ng Reactive Forms, I have a basic html input field for the password and warning paragraphs outlining the password requirements. <div class="field"> <label class="label">Password</label ...

Utilize RequireJS to load and initiate the primary ViewModel written in TypeScrypt

Recently, I started using requireJs and I'm facing a challenge. I want to load a viewmodel from my main script, App.ts, and retrieve a new instance of my viewModel: LienPdtUfActVM.ts. This is how my App.ts file looks like: declare var jQuery: JQueryS ...

Ways to identify browser version in Angular 4 to discourage IE usage

Is there a method in Angular 4 (TypeScript) for detecting the browser type? I am currently working with Angular 4 and would like to explore options for identifying the browser type when my application is loaded. I specifically want to prevent my applicati ...

How can I design a Typescript interface that accommodates both strings and other data types?

I am working on designing an interface that allows for an array of objects and strings to be stored. For instance: const array = [ '', {id: '', labels: ['']} ] I attempted to achieve this using the following code: export ...

What is the best way to remove specific records from a FirebaseTS Database using Angular 13?

Hi there! I'm still getting the hang of the Angular framework, so please bear with me. Currently, I have a feed or timeline consisting of simple posts that contain text. This text is stored in Firebase using the following method: firestore = new Fireb ...

Having difficulty accessing Req.Query in Express

I am currently facing an issue with retrieving the Query String data in order to utilize it as a parameter for my OpenWeather API call later on. Despite the Query String being visible in the URL request, I keep encountering "undefined" when attempting to ...