【问题标题】:Typescript: Property 'decoded' does not exists on type Request打字稿:请求类型上不存在“已解码”属性
【发布时间】:2016-05-17 03:06:47
【问题描述】:

我在 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.' 
    });

  }

想将其重写为打字稿但收到错误Property decoded does not exists on type Request

有什么办法解决这个问题吗?

【问题讨论】:

  • 你有Request的类型定义吗?
  • @VadimMacagon 是的,它来自express import {Request, Response} from "express";
  • 我在express.d.ts 中没有看到decoded 字段,这是您自己添加的字段吗?
  • @VadimMacagon 实际上是的,它是自定义字段。哦,那么最好的方法是什么?

标签: javascript node.js express typescript request


【解决方案1】:

如果您不想创建扩展 Request 的新类,您可以将 request 作为对象访问,例如:

req['decoded'] = decoded;

如果它仍然向您抛出,您可能必须将 req 转换为对象(打字稿):

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

您甚至可以将 req 转换为 type any 并将访问解码为属性(打字稿):

(<any>req).decoded = decoded;

【讨论】:

    【解决方案2】:

    您需要使用声明合并来为自定义 Request 字段添加类型定义。为此,请创建一个如下所示的 .d.ts 文件:

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

    并将其添加到您的编译上下文中,以便编译器将类型定义与 express.d.ts 中的类型定义合并。

    【讨论】:

    • 这是一种非常模糊的方法(虽然很常见)。我不会推荐它,它绝对不是最好的方法。
    • 我会向所有来这里寻求真正答案的人推荐这种方法,因为它是此页面上唯一真正有效的方法。
    【解决方案3】:

    即使可能,我也不会合并来自同名模块的接口。我宁愿创建一个新的自定义接口,您甚至可以在使用它的同一个文件中声明它。 (否则,直接导出)

    import {Request, Response} from "express";
    
    interface CustomRequest extends Request {
        decoded: string;
    }
    

    这样更简洁,而且更接近 OOP。

    【讨论】:

    • 这种方法只会导致追逐更多类型错误,例如错误TS2345: Argument of type '(req: CustomRequest, res: Response) =&gt; void' is not assignable to parameter of type 'RequestHandlerParams'. Type '(req: CustomRequest, res: Response) =&gt; void' is not assignable to type '(RequestHandler | ErrorRequestHandler)[]'. Property 'push' is missing in type '(req: CustomRequest, res: Response) =&gt; void'.
    • 你能提供一个你遇到这个问题的sn-p吗?我在扩展 express 的那些标准接口时从来没有遇到过问题。我想了解 1. 您的问题和 2. 否决票。您似乎使用了错误的类型...
    【解决方案4】:

    该错误意味着来自 express 的原始 Request 类型没有任何具有该名称的字段。

    您有两个选项来解决这个问题,第一个如Vadim Macagon 指出的那样,您可以创建一个声明模块文件并添加您的自定义字段,这样该字段将在每个请求中可用。

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

    选项二,您可以创建一个自定义接口,扩展原始请求并添加您的解码字段。

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

    然后在你的代码中

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

    第一个解决方案是将自定义字段“添加”到Request,第二个解决方案是添加字段并从请求扩展。

    在您的情况下,我会使用第一个解决方案来避免每次您必须使用请求中的 decoded 字段时编写 ICustomRequest(或您选择的任何名称),文件 .d.ts 不需要在您的代码中导入,这样您就可以创建文件并完成。

    【讨论】:

      【解决方案5】:

      我的“解码”只是 user_id 字符串,我这样解决了这个问题:

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

      【讨论】:

        【解决方案6】:

        我最近遇到了同样的问题,我遵循了之前 cmets 和这个 repo 中的解决方案,但我仍然遇到同样的问题。在进行更多挖掘之后,它似乎是 ts-node 的一个错误。

        要解决这个问题,您需要使用 --files 标志运行您的服务器

        所以如果你正常运行你的服务器 ts-node ./src/server.ts 或者 nodemon ./src/server.ts 把它改成 ts-node --files ./src/server.ts 或者 nodemon --files ./src/server.ts

        在那之后,我能够摆脱 VScode 错误和启动服务器时的错误。

        【讨论】:

          猜你喜欢
          • 2017-03-02
          • 2021-09-07
          • 1970-01-01
          • 2017-08-07
          • 2017-03-26
          • 2017-09-06
          • 2020-05-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多