Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript + Express : req.params

I have the following express route :

app.get('/:id', function (req, res) {
  var idNum: number = Number(req.params.id);
  var idCast: number = +req.params.id;
  var id: number = req.params.id;

  console.log('typeof idNum ', typeof idNum , '  ', 'idNum== 0 :  ', idNum== 0  , '  ', 'idNum=== 0 :  ', idNum=== 0);
  console.log('typeof idCast', typeof idCast, '  ', 'idCast == 0 :', idCast == 0, '  ', 'idCast === 0 :', idCast === 0);
  console.log('typeof id    ', typeof id    , '  ', 'id == 0 :    ', id == 0    , '  ', 'id === 0 :'    , id === 0);

  res.json({});
});

this returns :

typeof idNum  number    idNum== 0   : true    idNum=== 0   : true
typeof idCast number    idCast == 0 : true    idCast === 0 : true
typeof id     string    id == 0     : true    id === 0     : false

I understand that typescript provide only compile-time type-checking, and I guess it means it's not aware that req.params provide arguments as strings.

Is there any way I can automatically cast my params to Number ? or at least raise an error of I didn't done it manually ? Else, it seems that tympescript, unless used in a full-typescript environnement is useless.

Endly, is there any "big" open source project using TypeScript with ExpressJS that I could read the source from ?

like image 756
IggY Avatar asked Sep 06 '16 12:09

IggY


2 Answers

You can type the req object by extending the Request type provided by express with the following syntax:

Request<Params, ResBody, ReqBody, ReqQuery>

Therefore, in your example, you could do something like the following to explicitly declare that your property is an incoming string to ensure you convert it to a Number type:

import { Request } from "express"

...

app.get('/:id', function (req: Request<{ id: string}>, res) {
  
...
like image 149
Sators Avatar answered Oct 23 '22 07:10

Sators


It seems that the req.params is any so the compiler has no way of knowing that the value for id is string, BUT of course it's a string as it comes as a path param which are always strings.

You should be able to deal with it using a router middleware, something like:

router.use(function (req, res, next) {
    if (req.params && req.params.id && typeof req.params.id === "string") {
        let num = Number(req.params.id);
        if (!isNaN(num)) {
            req.params.id = Number(req.params.id);
        }
    }
    next();
});

That should convert all params named id (which are strings) into numbers.

like image 20
Nitzan Tomer Avatar answered Oct 23 '22 07:10

Nitzan Tomer