*覆盖*node_modules 中第三方 TypeScript 类型的最佳方法

ris*_*ott 14 node.js npm typescript

在许多情况下,通过专用包或与 npm 包本身一起提供的第三方类型定义@types/*后来被发现不完整或与新的依赖项不兼容。

因此,我正在寻找一种直接的方法来覆盖node_modules. 理想情况下,我只需将它们复制粘贴到我的存储库中,并告诉 TypeScript 编译器使用我的类型即可。

我找到了 3 种可能的解决方案,但没有一个特别好:

声明环境模块

declare module 'printer' {
   export function print(msg: string): void;
}

declare module 'printer/color' {
   export function print(msg: string, color: string): void;
}

// WARNING: If you `import` or `export` anything here,
// this will suddenly *augment*, not *override* the
// 'printer' module.
Run Code Online (Sandbox Code Playgroud)
缺点
  • 无法简单地复制并粘贴损坏的类型,node_modules因为
    • 你必须把它包起来declare module 'printer' {}
    • 子模块(例如import print from 'printer/color')必须显式声明为单独的模块声明。
    • 原始类型很可能使用import/ export,因此需要重写才能在环境模块中工作。
  • 无法覆盖现有的环境模块(例如,declare module 'fs' {}只会增加@types/nodenot override 的类型)

重新映射 tsconfig 中的路径

declare module 'printer' {
   export function print(msg: string): void;
}

declare module 'printer/color' {
   export function print(msg: string, color: string): void;
}

// WARNING: If you `import` or `export` anything here,
// this will suddenly *augment*, not *override* the
// 'printer' module.
Run Code Online (Sandbox Code Playgroud)
优点
  • 实际上可以逐字复制粘贴 node_modules 中的类型并应用您自己的修复。
缺点
  • 子模块(例如import bar from 'printer/color')必须显式声明为单独的路径映射。
  • 无法覆盖现有的环境模块(例如@types/node

安装本地包

// tsconfig.json
{
  "baseUrl": "./",
  "paths": {
    "printer": ["types/printer"],
    "printer/color": ["types/printer/color"],
  }
}
Run Code Online (Sandbox Code Playgroud)

优点

  • 无论原始类型如何编写,它们都不会被安装

缺点

  • 虽然适用于专用@types/*包,但它不适合发布自己类型的包,因为您将有效地获得运行时代码的所有权,这意味着您将错过安全修复等。

TypeScript 文档似乎没有讨论这个常见问题的解决方案,但我想知道是否有人有一个更强大、警告更少的解决方案?