TypeScript:扩展第三方库的类型定义

内容列表

TypeScript 作为 JavaScript 的超集,为 Web 开发带来了强类型语言和类似代码智能提示这种良好的开发体验,而代码提示依赖于类型定义文件。类型定义文件的发展也经历了一个逐步演变的过程,从最初基于 JavaScript 编写的 npm 包,通过社区方案来引入类型定义包,再到目前多数模块基于 TypeScript 编写并在发布时带上类型定义文件这种最佳方案,开发者体验得到进一步的提升。

不过,在使用类型定义文件的过程中我们通常需要和类型定义进行交互,大多数场景可以通过泛型来解决;而有一个典型场景就是需要我们扩展第三方库的类型定义,避免在多个文件中编码时都要引入类型定义的麻烦。可能不是很好理解,在这里通过一个实际的例子就可以解释清楚。

使用 koa2 框架进行 Node 应用开发时,为了利用 TypeScript 带来的优势,需要引入类型定义,而该框架本身是用 JavaScript 编写的,不过可以通过安装社区提供的 @types/koa 包来获得支持。koa2 框架可以通过扩展 context 对象来引入一些工具,最典型的就是日志管理,这里使用 koa-log4,在 context 上挂载一个 logger 属性引用日志打印器实例,可以通过泛型的方式扩展应用实例上下文对象的定义,但在多个文件中就显的比较麻烦了,开发体验最好且最自然的方式就是直接一次扩展 koa2context 类型定义,后续在多个文件中不用使用泛型即可自动获得代码提示。

这里直接给出最终代码:

// src/@types/index.d.ts
import log4js from "koa-log4";

declare module "koa" {
  interface DefaultContext {
    logger: log4js.Logger;
  }
}

起初,我认为 TypeScript 官方会对这种典型的场景给出明确的方案文档,但找了很久没找到,就去 Google,在 StackOverflow 上发现有人提及类似以上的方案,经过实验确实解决了问题。但是,我一般会找到明确的官方文档记录一下,以备后续参考,也是秉行尽量不 Hack 以官方且优雅的方式解决问题的原则,经过非常仔细的查找之后,确实在官方文档中找到了,但非常分散。

至此,就比较完美的解决了这个问题。而这个问题也是很久之前就解决的,回过头来发现记录下来会更好一些。

参考资源

相关

浏览器对象模型(BOM)

2018-05-15

在网页开发中,我们通常专注于内容的设计,而有些时候我们需要进行不同窗口之间的交互,这时候我们就需要学习如何运用 BOM 中的许多核心对象,及其属性、方法。

了解更多

Child process API: spawn vs exec

2021-08-25

使用 Node.js 编写一些脚本工具是非常方便的,而常用的 spawn 与 exec API 有什么不同呢?

了解更多

主流小程序开发流程

2022-11-11

微信小程序开发与钉钉小程序开发的移动端兼容上有很多需要注意的点。

了解更多