0

I am in the process of rewriting my JS-based express app into Typescript. While I was refactoring my router instances, I stumbled upon the following issue:

this.router.get('/tenantInfo', (req, res) => {
  res.send(this.getTentantInfo(req.tenant))
})

When I want to transform this into Typescript it would look something like this:

import express, { Request, Response, Router } from 'express'

this.router.get('/tenantInfo', (req: Request, res: Response) => {
  res.send(this.getTentantInfo(req.tenant))
})

which leads to an error in req.tenant since Request does not have this property. I searched Stackoverflow and found this answer, however, I think that this will not lead to a good application structure if I just extend the Request interface of express with each and every additional property that I will expect in various places of my application.

What would be a nice approach to solve this in a clean and maintainable manner?

nymvno
  • 370
  • 5
  • 19
  • Extending the `Request` interface is the way to go. `...if I just extend the Request interface of express with each and every additional property that I will expect in various places of my application`, that's the point of TypeScript! – Owl Mar 22 '21 at 13:03

2 Answers2

0

You may need to check for a tenant before using it, for example:

this.router.get('/tenantInfo', (req: Request, res: Response) => {
  if(req.tenant){
      res.send(this.getTentantInfo(req.tenant))
  }

  res.send({
     message: "Your error message..."      
  })
})

I'm not sure, but test and see if it solves your problem

  • 1
    This would be the JS solution of the problem in order to prevent runtime issues. But in this case it is the same with the if-clause having the same error as before – nymvno Mar 22 '21 at 12:38
0

This probably won't add much to my comment, but you can also separate the .d.ts file to multiple places. Lets say you have this directory structure

.
└── src
    ├── tenant
    │   ├── request.d.ts
    │   └── routes.ts
    ├── some
    │   ├── interface.ts
    │   ├── some.d.ts
    │   └── routes.ts
    ├── other
    │   └── ...
    └── stuff
        └── ...

In tenant/request.d.ts

declare namespace Express {
  interface Request {
    tenant?: string;
  }
}

In some/interface.ts

export interface Some {
  foo: string;
  bar: string;
}

and in some/request.d.ts

import { Some } from "./interfaces"; 

declare namespace Express {
  interface Request {
    some?: Some;
  }
}

Same goes with other and stuff...

Owl
  • 6,337
  • 3
  • 16
  • 30