0

I'm trying the express route handlers that comes with the documentation to make a chain of function calls in certain order, so I want to pass a value from cb0 to cb1 (or cb2), currently I'm setting a property in the req object and accesing it from another handler, this just work fine.

const express = require('express');
const app = express();
const PORT = 8000;

const cb0 = function (req, res, next) {
  console.log('CB0');
  req.cb0val = 'Hello';
  next();
}

const cb1 = function (req, res, next) {
  console.log('CB1');
  req.cb1val = 'World';
  next();
}

const cb2 = function (req, res) {
  res.send(`Hey, ${req.cb0val} ${req.cb1val}`);
}

app.get('/', [cb0, cb1, cb2])

app.listen(PORT, () => {
  console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);
});

The problem came when using typescript

import express from 'express';
const app = express();
const PORT = 8000;

const cb0: express.RequestHandler = function (req: express.Request, res: express.Response, next: Function) {
  console.log('CB0');
  req.cb0val = 'Hello';
  next();
}

const cb1: express.RequestHandler = function (req: express.Request, res: express.Response, next: Function) {
  console.log('CB1');
  req.cb1val = 'World';
  next();
}

const cb2: express.RequestHandler = function (req: express.Request, res: express.Response) {
  res.send(`Hey, ${req.cb0val} ${req.cb1val}`);
}

app.get('/example/c', [cb0, cb1, cb2])

app.listen(PORT, () => {
  console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);
});

Because I'm setting the type of req as express.Request I can't set a new property of that type getting the following errors:

index.ts:7:7 - error TS2339: Property 'cb0val' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

7   req.cb0val = 'Hello';
        ~~~~~~
index.ts:13:7 - error TS2339: Property 'cb1val' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

13   req.cb1val = 'World';
         ~~~~~~
index.ts:18:24 - error TS2339: Property 'cb0val' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

18   res.send(`Hey, ${req.cb0val} ${req.cb1val}`);
                          ~~~~~~
index.ts:18:38 - error TS2339: Property 'cb1val' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

18   res.send(`Hey, ${req.cb0val} ${req.cb1val}`);
                                        ~~~~~~

What's the correct approach to handle this scenario without changing the type of express.Request to any?

0

1 Answer 1

1

You can use something called Declaration Merging.

Create a file called express.d.ts somewhere in your project. This is typically created in a @types folder in the root of your project (@types/express.d.ts).

The contents of this file should be

declare namespace Express {
    interface Request {
        cb0val: string
        // other custom properties ...
    }
}

In your tsconfig, setup either a typeRoot or add the new file to the types field.

"typeRoots": [
  "@types/",
  "node_modules/@types/"
]
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.