简体   繁体   中英

Typescript: Property 'decoded' does not exists on type Request

I have this code in javascript:

if (token) {

    // verifies secret and checks exp
    jwt.verify(token, Config.Secret, function(err, decoded) {      
      if (err) {
        return res.json({ success: false, message: 'Failed to authenticate token.' });    
      } else {
        // if everything is good, save to request for use in other routes
        req.decoded = decoded;    
        next();
      }
    });

  } else {

    // if there is no token
    // return an error
    return res.status(403).send({ 
        success: false, 
        message: 'No token provided.' 
    });

  }

Want to rewrite it to typescript but getting an error Property decoded does not exists on type Request .

Any ideas how to solve that?

If you don't want to make a new class extending Request you may access request as an object like:

req['decoded'] = decoded;

If it stills throws at you you may have to cast req as an object (typescript):

(<Object>req)['decoded'] = decoded;

You may even cast req to type any and access decoded as property (typescript):

(<any>req).decoded = decoded;

You will need to use declaration merging to add type definitions for custom Request fields. To do so create a .d.ts file that looks like this:

declare module Express {
  export interface Request {
    decoded: string;
    // etc.
  }
}

And add it to your compilation context so the compiler merges the type definitions with the ones in express.d.ts .

I would not merge interfaces from modules with the same name even if it's possible. I would rather make a new custom interface, which you can even declare in the very same file you are using it. (otherwise, just export it)

import {Request, Response} from "express";

interface CustomRequest extends Request {
    decoded: string;
}

This is much more cleaner and moreover it's closer to OOP.

That error mean that the original Request type from express don't any field with that name.

You have two options to solve this problem, the first one as Vadim Macagon pointed out, you can create a declaration module file and add your custom field, doing so that field will be avaliable on every Request.

declare module Express {
  export interface Request {
    decoded: string;
    // etc.
  }
}

Option two you can create a custom interface that extends the original Request and add your decoded field.

export default interface ICustomRequest extends Request {
  token: string;
}

and then in your code you

app.post('/', function (req: ICustomRequest, res) {
  req.decoded = decoded; // No errors here
});

The first solution you're "adding" the custom field to the Request , and the second you're add your field and extending from Request.

In your case I would use the first solution to avoid writing ICustomRequest (or whatever name you choose) every time that you have to use that decoded field from your request, the files .d.ts don't need to be imported in your code so you can just create the file and it's done.

my 'decoded' was just user_id string and i solved this problem like this:

req.body.decoded = decoded;    
next();

I recently had the same issue, I followed the solution in the previous comments and this repo and I still had the same issue. After doing more digging it seems like it's a bug with ts-node.

To solve this you need to run your server with a --files flag

So if you normally run your server ts-node ./src/server.ts or nodemon ./src/server.ts Change it to ts-node --files ./src/server.ts or nodemon --files ./src/server.ts

After that, I was able to get rid of both the VScode errors and errors while starting the server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM