使用 Typescript 扩展 Express Request 对象

新手上路,请多包涵

我正在尝试添加一个属性来使用打字稿从中间件表达请求对象。但是我不知道如何为对象添加额外的属性。如果可能的话,我宁愿不使用括号表示法。

我正在寻找一种解决方案,可以让我写出类似的东西(如果可能的话):

 app.use((req, res, next) => {
    req.property = setProperty();
    next();
});

原文由 Isak Ågren 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

您想创建一个自定义定义,并使用 Typescript 中名为 Declaration Merging 的功能。这是常用的,例如在 method-override 中。

创建一个文件 custom.d.ts 并确保将其包含在您的 tsconfig.jsonfiles 中(如果有)。内容可以如下所示:

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

这将允许您在代码中的任何位置使用如下内容:

 router.use((req, res, next) => {
    req.tenant = 'tenant-X'
    next()
})

router.get('/whichTenant', (req, res) => {
    res.status(200).send('This is your tenant: '+req.tenant)
})

原文由 maximilianvp 发布,翻译遵循 CC BY-SA 4.0 许可协议

正如 index.d.ts 中的评论 所建议的,您只需向全局 Express 命名空间声明任何新成员。例子:

 declare global {
  namespace Express {
    interface Request {
      context: Context
    }
  }
}

完整示例:

 import * as express from 'express';

export class Context {
  constructor(public someContextVariable) {
  }

  log(message: string) {
    console.log(this.someContextVariable, { message });
  }
}

declare global {
  namespace Express {
    interface Request {
      context: Context
    }
  }
}

const app = express();

app.use((req, res, next) => {
  req.context = new Context(req.url);
  next();
});

app.use((req, res, next) => {
  req.context.log('about to return')
  res.send('hello world world');
});

app.listen(3000, () => console.log('Example app listening on port 3000!'))

更多的

扩展全局命名空间也包含 在 TypeScript Deep Dive 中。

原文由 basarat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题