首页 > 解决方案 > 为什么要在 DefinitiveTyped 上为 Javascript 库发布 TypeScript 声明文件?

问题描述

我在 npm 上发布了两个 Javascript 库,用户要求为它们提供 TypeScript 类型定义。我自己不使用 TypeScript,也没有计划在 TypeScript 中重写这些库,但如果只是为了更好地完成 IntelliSense 代码,我仍然想添加类型定义文件。我正在为此寻求一些建议。

我开始阅读DefinitelyTyped 项目的文档和关于发布npm 包的声明文件的文档。两个消息来源都指出,“在 npm 上发布到 @types 组织”是不是用 TypeScript 编写的项目的首选方法。

为什么这比通过typesin 中的字段与库本身一起发布类型定义更受欢迎package.json?我真的不明白让第三方参与其中的意义。似乎更新类型定义和版本化它们只是这样更复杂。

上面引用的文档中的引用(强调我的)

来自DefiniteTyped:

如果您是库作者并且您的包是用 TypeScript 编写的,请将自动生成的声明文件捆绑到您的包中,而不是发布到绝对类型。

来自 typescriptlang.org:

现在您已经按照本指南的步骤创建了一个声明文件,是时候将其发布到 npm 了。您可以通过两种主要方式将声明文件发布到 npm:

  • 与你的 npm 包捆绑在一起,或者
  • 在 npm 上发布到 @types 组织。

如果您的包是用 TypeScript 编写的,那么首选第一种方法。使用 --declaration 标志生成声明文件。这样,您的声明和 JavaScript 将始终保持同步。

如果你的包不是用 TypeScript 编写的,那么第二种是首选方法。

两者似乎都在说:

if (isAuthor && lang === "typescript")
  bundle();
else
  publishOnDefinitelyTyped();

标签: javascripttypescriptnpmtypescript-typingsdefinitelytyped

解决方案


类型声明发布指南在几个方面似乎有点过时和稀疏。

我将尝试详细比较这两种情况。

1. 与 npm 包捆绑在一起的类型

1.1。从包装消费者的角度

1.1.1。优点

通常,由于简化的依赖管理,包捆绑类型更方便。

  • 不需要额外的@types 依赖(添加包依赖)
  • 不需要在包和它的类型之间同步版本(升级包依赖)

1.1.2。缺点

  • 选择退出使用包捆绑类型的有限方法

    涉及消费者需要修改或替换类型声明的情况。

    由于配置选项已经有限,该过程在具有自以为是的构建设置的项目中可能会出现相当大的问题。

1.2. 从包作者的角度来看

1.2.1。优点

  • 库所有者可以按照他的意愿,以任何频率或时间表发布补丁和类型声明的更新
  • 对第三方或外部类型依赖没有限制
  • 以与实际代码相同的方式为多个版本提供并发支持

1.2.2。缺点

将类型与包捆绑在一起意味着实际上每次发布一个版本时都会发布两个 API 合约。

例子:

让我们假设一个旨在符合 semver 版本控制的库。

  • 最新版本 -> 1.0.0
  • 由于重大更改-> 2.0.0,主要版本被碰撞
  • 报告了类型声明中的一个严重错误,对于使用 typescript 项目的一组用户,该版本被破坏
  • 类型的修复是一项重大更改

下一个版本的选项是:

A. 2.XX -> 违反类型声明的 semver 规则

B. 3.0.0 -> 违反实际代码的 semver 规则

这种情况可能有很多变体。

2. 发布到绝对类型的存储库

2.1。从包装消费者的角度

2.1.1。优点

  • 通过删除 @types 依赖项进行简单的选择退出

2.1.2. 缺点

  • 包消费者负责保持包和相关类型的版本同步

2.2. 从包作者的角度来看

2.2.1。优点

  • 类型对包的发布周期没有影响

  • DT repo 带有两个额外的特征:

    • 用于类型断言和类型测试的 dts-lint 库
    • 深入的性能和编译器占用分析,包括最新包版本和 PR 修改后的包之间的差异。

    第一个工具可以轻松地合并到另一个包 repo 中。我不确定分析是否可以在自己的存储库中复制,但它包含很多有价值的数据。

2.2.2。缺点

  • 支持过去版本的非标准方式

  • 受 DT 审查和发布周期约束的类型发布计划

    假设 DefinitiveTyped PR 创建者是 @types 包所有者,通常需要一到两天才能合并 PR。此外,在 types-publisher 更新 PR 相关的 @types npm 包之前会有一点延迟。

    当 PR 是作者对给定包的第一次贡献时,会涉及额外的审查过程。

  • 使用外部依赖

    TypeScript 手册说:

    如果您的类型定义依赖于另一个包:

    不要把它和你的结合起来,把它们放在自己的文件里。

    也不要复制包中的声明。

    如果它不打包其声明文件,请依赖 npm 类型声明包。

    从冗余实用程序类型的数量来看,这些几乎没有受到尊重。

    类型声明的作者可以使用相邻的 DT 存储库类型。取决于此列表之外的包,要求它们在类型发布者白名单上。

    可以通过向 types-publisher 提交 PR 来将新包列入白名单。我的 PR 花了两个多星期才被合并。我不知道这是否正常,因为我提交了一个 PR。

  • DT 回购量

    我没有跨 IDE 比较或经验,但就 JetBrains IDE 而言,完全索引的 DT repo 项目的内存占用使 IDE 无法使用。

    禁用对更改的重新编译在一定程度上有所帮助。可以通过删除与感兴趣的包无关的 DT 存储库内容来解决令人沮丧的 IDE 体验。


推荐阅读