news 2026/7/3 21:39:47

拓展-01-Express 类型扩展笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
拓展-01-Express 类型扩展笔记

1. Express 的类型是怎么设计的

@types/express故意留了一个「可扩展的口子」。

@types/express-serve-static-core里大致是这样:

declareglobal{namespaceExpress{// 空接口,专门给你扩展用的interfaceRequest{}interfaceResponse{}}}exportinterfaceRequest<...>extendshttp.IncomingMessage,Express.Request{// get、params、body 等都在这里}

关键关系:

你扩展的 Express.Request(全局) ↑ 继承 express 导出的 Request

所以:不是直接改import { Request } from "express"的定义,而是扩展全局的Express.Request。扩展成功后,所有extends Express.Request的地方都会自动带上你的字段。

2. 声明合并:TypeScript 的核心机制

TypeScript 允许同名interface自动合并:

interfaceUser{name:string;}interfaceUser{age:number;}// 等价于:// interface User { name: string; age: number; }

namespace+interface也支持合并:

namespaceExpress{interfaceRequest{userId?:number;}}// 会和 @types/express 里已有的 Express.Request 合并

记住一条规则:interface可以合并,type别名不行。

3. 为什么需要declare global

你的增强写在自己的文件里,不是在@types/express包内部。

文件有两种身份:

身份判断条件顶层声明落在哪
脚本(script)没有import/export直接进全局
模块(module)importexport只在模块内,不进全局

Express命名空间定义在全局里。你的.d.ts如果是模块,里面的namespace Express默认只是模块局部的,合并不了全局那个。

下面两种写法二选一,不要两种都写。

模块写法(推荐)— 文件里会有import/export(例如配合export {})时使用:

declareglobal{namespaceExpress{interfaceRequest{userId?:number;}}}

含义:「虽然这个文件是模块,但请把里面的声明放进全局作用域。」

脚本写法— 整个.d.ts没有任何import/export时可直接写:

namespaceExpress{interfaceRequest{userId?:number;}}

怎么选

这个 .d.ts 里会不会出现 import? ├── 不会 → 直接写 namespace Express { ... } 就行 └── 会 / 不确定 → 用 declare global + export {}

4. 为什么需要export {}

declare global只能在模块里用。

你的文件如果只有declare global { ... },没有import/export,TypeScript 会把它当脚本,declare global要么报错,要么不生效。

export{};

作用:把文件标记成模块,且:

  • 不导出任何实际值
  • .d.ts编译后不会产生 JS
  • 这是社区里最常用的「零副作用模块标记」

等价写法还有:

import"express";// 也可以,但会多一层对 express 的依赖引用exporttype{};// 也可以

口诀:用了declare global,文件末尾就要有importexport

5. 你的文件逐块理解(完整心智模型)

declareglobal{// ① 在模块里,把下面内容注入全局namespaceExpress{// ② 找到全局 Express 命名空间interfaceRequest{// ③ 与已有 Request 合并(不是覆盖)userId?:number;// ④ 新增可选字段}}}export{};// ⑤ 让本文件成为模块,① 才合法

五句话对应五个概念:全局注入 → 命名空间 → 接口合并 → 字段定义 → 模块标记

6.tsconfig.jsoninclude要覆盖到它

类型声明文件要被 TypeScript 读到,include需覆盖到.d.ts所在目录。例如本项目的配置:

{"compilerOptions":{xxx},"include":["**/*.ts"],"exclude":["node_modules"]}

其中"include": ["**/*.ts"]会匹配**/*.d.ts,因此src/types/express.d.ts会被纳入编译。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 21:38:13

2026年湖南大学人工智能相关专业培养与保研发展解析

2026年湖南大学人工智能相关专业培养与保研发展解析不少关注人工智能赛道、看重本科保研路径的高考生和家长&#xff0c;会在重点高校中寻找培养体系完善、保研支撑充足的院校。2026年湖南大学的本科招生季&#xff0c;该校人工智能相关专业的培养资源与保研路径设计&#xff0…

作者头像 李华
网站建设 2026/7/3 21:38:42

淄博黄金白银回收铂金旧金回收无套路门店 TOP 榜单 实地测评资料整理

淄博的黄金白银回收店铺星罗棋布&#xff0c;铂金旧金回收市场更是鱼龙混杂&#xff0c;市民想找到靠谱变现渠道难免挑花眼。为帮大家甄别诚信商户&#xff0c;小编实地走访多家门店&#xff0c;筛选出本地正规回收清单。收录商户既有连锁老牌机构&#xff0c;也有深耕本土多年…

作者头像 李华
网站建设 2026/6/27 5:23:54

ins红人营销执行清单:视觉种草、UGC素材与数据追踪

ins红人营销要做出稳定结果&#xff0c;核心不是一次性找多少达人&#xff0c;而是能不能把筛选、建联、内容、发布和复盘变成可复制流程。尤其在亚马逊测评阶段&#xff0c;品牌需要先判断目标市场、用户痛点和内容表达方式&#xff0c;再决定用什么类型的达人组合。在CSDN这类…

作者头像 李华
网站建设 2026/6/27 5:23:21

最小二乘法与机器学习正规方程

每个样本都有误差 eiyi^−yi​e_i \hat{y_i} - y_i​ei​yi​^​−yi​​&#xff0c;如果直接把误差相加&#xff0c;会正负互相抵消&#xff0c;所以把误差平方&#xff1a; Loss:J(θ)∑i(yi^−yi​)2 Loss:J(\theta) \sum_i(\hat{y_i} - y_i​)^2 Loss:J(θ)i∑​(yi​^​…

作者头像 李华
网站建设 2026/6/27 5:20:15

第一章Netty,transferTo核心用法理解

基于前文对 FileChannel 零拷贝特性及 transferTo 核心用法的讨论,以下是一个‌生产级‌的完整示例。该示例展示了如何利用 transferTo 高效复制大文件,并处理了‌分块传输‌、‌资源管理‌及**异常捕获等关键细节。 先来个简单的示例预热一下: public class FileChannelT…

作者头像 李华