- 原文地址:How to Create Custom Headers with Express and TypeScript
- 原文作者:Anthony Luzquiños
- 译文出自:掘金翻译计划
如何用Express和TypeScript创建Custom Headers

最近,我需要创建一个云函数,将一些数据存储在 PostgreSQL 数据库。一旦我完成了所有事情,或者至少完成了最少的功能,我必须为我的终端添加某种基本身份验证。没什么特别,我们只是在这里使用了一个自定义的标准 header,“enterprise-key”,它会告诉我哪个客户端正在调用请求。
你可能认为这很容易,但我研究了将近5个小时才弄清楚如何实现它。我想帮助任何和我遇到同样问题的人,所以我决定写这篇文章。那么我们开始吧!
如果你对 Node.js, Express, TypeScript 等有所了解,你需要做的第一件事是创建 CustomRequest 接口,该接口继承 Request ,如下所示:
import { Request } from 'express';
interface CustomRequest extends Request {}
export { CustomRequest };
至此为止还挺好。此时,我们可以添加任意数量的属性,但它们是可选的(使用 ? 运算符),例如:
import { Request } from 'express';
interface CustomRequest extends Request {
myAwesomeProperty?: number;
}
export { CustomRequest };
上述这样做,你能访问 request 对象属性 myAwesomeProperty。现在你可能认为下一步是创建一个键名为 headers 的属性并定义为对象,然后在其中添加我们的新属性,例如 customHeader :
import { Request } from 'express';
interface CustomRequest extends Request {
enterpriseID?: number;
headers: {
customHeader?: string;
};
}
export { CustomRequest };
如果你使用上述代码并尝试访问 headers 的 customHeader 属性,你将会在编译阶段出现一个巨大的错误,例如:
No overload matches this call. (...)
Types of property 'headers' are incompatible.
Property 'customHeader' is missing in type 'IncomingHttpHeaders' but required in type '{ customHeader: string; }'.ts(2769)
一切从这里开始。像往常一样,这是一个非常复杂且难以理解的错误,但我们可以解决它。你可能注意到这里重要的是IncomingHttpHeaders 类型和我们的 customHeader 属性。如果你检查 Request 的定义,你会注意到它继承自 core.Request 接口,而后者又继承自 http.IncomingMessage 类,并且这个类有一个名为 headers 的属性,猜猜是什么?它的类型是 IncomingHttpHeaders(出自 http 模块)。我们找到解决方案了。
所以现在我们知道 headers 属于某种类型,但是我们不能在 Typescript 中扩展一个类型,对吧?好吧,从严格意义上来说,这可能是对的,但是有一种方法可以在 Typescript 中扩展类型(请查看文档了解更多信息)。这样做的方法是使用 intersection,当我们将两个或多个类型相交时,我们通过使用 & 运算符创建一个新类型。因此,我们的下一步将从 http 导入 IncomingHttpHeaders 并将其与我们的自定义header(s) 相交。
import { IncomingHttpHeaders } from 'http';
import { Request } from 'express';
interface CustomRequest extends Request {
myAwesomeProperty?: number;
headers: IncomingHttpHeaders & {
customHeader?: string;
};
}
export { CustomRequest };
我们讲完了吗?并没有。如果这篇文章你看到这,你可能遇到和我一样遇到同样的错误——每当我试图访问 customHeader ,则返回未定义,根本没有明显的原因。如果没有任何解释,你可能无法访问新的自定义 header 。但是这里有一种解决方案!只需将 customHeader 属性更改为短横线连接书写即可:custom-header 或 Custom-Header 就可以了,现在通过使用括号 (req.headers['custom-header']) 能够访问你自己的 headers。
为什么我们必须这样做?为什么 Express 在使用驼峰命名似乎无法访问自定义 header ?我不知道,但是你如果知道,请随时在评论区留言原因,我们都可以从你的回答中收益。
这是我的第一篇文章,如果有任何错误,提前道个歉,英文不是我的第一语言,但我尽力了。
最后,如果你有空闲时间,请看看我的 npm cli 工具 simba.js 。它类似于 cra ,但适用于后端开发,它使用了MongoDB、Express和 TypeScript。并且通过一个简单的命令,你将拥有一个运行着一些你可能会觉得有用的终端的服务器。
愉快编码吧!