18

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 ?

2 Answers 2

32

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) {
  
...
Sign up to request clarification or add additional context in comments.

Comments

9

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.

3 Comments

Thanks for the answer, but it looks like really dirty to me to do that :/
I doubt that you'll find a more "automatic" way of doing that. The middleware feature is there for cases just like this one.
If you know that id is coming as number from the client url or in api request, No need to check is it string or not, we can type cast directly. Like const id = Number(req.params.id)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.