为什么要在 Javascript 库的 DefinitelyTyped 上发布 TypeScript 声明文件?

Why publish the TypeScript declaration file on DefinitelyTyped for a Javascript library?

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

我开始阅读 DefinitelyTyped project and the documentation on publishing a declaration file for an npm package 的文档。两个消息来源都指出“在 npm 上发布到 @types 组织”是不是用 TypeScript 编写的项目的首选方法。

为什么这比通过 package.json 中的 types 字段与库本身一起发布类型定义更受欢迎?我真的不认为让第三方参与其中有什么意义。似乎通过这种方式更新类型定义和版本控制更加复杂。

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

来自 DefinitelyTyped:

If you are the library author and your package is written in TypeScript, bundle the autogenerated declaration files in your package instead of publishing to Definitely Typed.

来自typescriptlang.org:

Now that you have authored a declaration file following the steps of this guide, it is time to publish it to npm. There are two main ways you can publish your declaration files to npm:

  • bundling with your npm package, or
  • publishing to the @types organization on npm.

If your package is written in TypeScript then the first approach is favored. Use the --declaration flag to generate declaration files. This way, your declarations and JavaScript will always be in sync.

If your package is not written in TypeScript then the second is the preferred approach.

两者似乎都在说:

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

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

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

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

1.1。从包装消费者的角度

1.1.1。优点

一般来说,由于简化了依赖管理,包捆绑类型更方便。

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

1.1.2。缺点

  • opt-out使用包捆绑类型的有限方法

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

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

1.2。从包作者的角度来看

1.2.1。优点

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

1.2.2。缺点

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

示例:

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

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

下一版本的选项是:

一个。 2.X.X -> 违反类型声明的 semver 规则

乙。 3.0.0 -> 违反实际代码的 semver 规则

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

2。发布到明确类型的存储库

2.1。从包装消费者的角度

2.1.1。优点

  • 简单 opt-out 通过删除 @types 依赖

2.1.2。缺点

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

2.2。从包作者的角度来看

2.2.1。优点

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

  • DT repo 有两个额外的特性:

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

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

2.2.2。缺点

  • non-standard 支持过去版本的方式

  • 受 DT 审核和发布周期限制的类型发布时间表

    假设 DefinitelyTyped PR 创建者是 @types 包的所有者,通常 在合并 PR 之前需要一到两天。此外,还有一个未成年人 在 types-publisher 更新 PR 相关 @types npm 包之前延迟。

    如果 PR 是作者对给定包的第一个贡献,则涉及额外的审查过程。

  • 使用外部依赖项

    TypeScript 手册说:

    If your type definitions depend on another package:

    Don’t combine it with yours, keep each in their own file.

    Don’t copy the declarations in your package either.

    Do depend on the npm type declaration package if it doesn’t package its declaration files.

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

    允许类型声明的作者使用相邻的 DT 存储库类型。 根据此列表之外的包,它们需要在 types-publisher 白名单中。

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

  • DT 回购量

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

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