Skip to content

贡献开源代码:Definitely Typed 贡献小记

约 1615 字大约 5 分钟

JavaScript / TypeScript

2025-03-10

TypeScript 开发者肯定对 npm install @types/*这个命令不陌生。是的,由于各种各样的原因,很多 npm 包并不是使用 TypeScript 编写的,这也就导致其缺少类型系统,难以获得 IDE 的类型推断支持。

因此出现了开源项目 DefinitelyTyped。该项目旨在为 JavaScript 编写的 npm 包提供高质量的 TypeScript 类型定义。任何人都可以为 JS npm 包添加类型定义,供社区中的所有人使用。

顺便,我也借着为 @cesium-china/cesium-map这个 JS npm 包添加类型定义的机会,阐述一下该如何规范地为开源项目贡献代码。

为开源项目贡献代码,不能直接在原项目上修改。而是要将开源项目仓库(称为上游仓库,upstream repo)fork 到你的账号下,成为你自己的仓库(称为远程仓库,remote repo)。然后将远程仓库 clone 到本地(称为本地仓库,local repo),在此基础上进行修改。

因此一个规范的贡献流程是:

  1. 将上游仓库 fork 到你的账号下,称为远程仓库。
  2. 将远程仓库 clone 到本地,称为本地仓库。
  3. 在本地仓库中创建一个开发分支,在开发分支上进行修改。
  4. 在修改过程中,如果有远程需求,可以随时提交到远程仓库中(注意不是上游仓库)。
  5. 在一切都修改、测试完成后,提交 PR 到上游仓库。

1 创建开发分支

来到 DefinitelyTyped/DefinitelyTyped 仓库中,将其 fork 到你的账号下。

1741607484816

操作完成后,你的账号下应该会多一个 <用户名>/DefinitelyTyped仓库,并且显示该仓库“forked from DefinitelyTyped/DefinitelyTyped”。

1741607593732

使用 git clone命令将你的仓库克隆到本地,并使用 git checkout -b命令或者你喜欢的 Git 可视化工具创建一个新分支。

提示

再次进行三个仓库的辨析,因为这真的很重要。

此处的上游仓库DefinitelyTyped/DefinitelyTyped仓库。

此处的远程仓库<用户名>/DefinitelyTyped仓库。

此处的本地仓库为你克隆到本地的<用户名>/DefinitelyTyped仓库

我真的推荐使用如 VSCode 或者 IDEA 等自带的 Git 可视化工具。2025年了,这些可视化工具已经能胜任绝大部分的 Git 任务,真没必要抱着命令行不放。

DefinitelyTyped而言,其分支命名应该被你所要添加类型定义的 JS npm 包来决定。如果这个包名不包含“@”和“/”,那就以这个包的名字为分支名;否则,你应该按照下面的示例命名分支。

JS npm 包DefinitelyTyped 分支名
example-packageexample-package
@cesium-china/cesium-mapcesium-china__cesium-map

也就是去掉“@”字符,并将“/”转为双下划线“__”。

然后在本地仓库的开发分支中进行修改。

注意

任何时候都不要直接修改主分支的代码!

主分支代码只能通过 PR 或 Merge 进行修改。

2 编写类型声明

按照DefinitelyTyped的规范,类型声明文件都应该存放至/types/<Package-name>/文件夹。

如我要贡献的@cesium-china/cesium-map的类型声明,其声明文件应该放在/types/cesium-china__cesium-map/index.d.ts中。

这里不建议自己添加类型声明文件,而是使用dts-gen来创建模板。

回到DefinitelyTyped,执行

pnpm install -g dts-gen
pnpx dts-gen –-dt –-name cesium-china__cesium-map -–template module

此时你会发现,在对应的包文件夹中出现了一系列的文件。

  • DefinitelyTyped
    • types
      • cesium-china__cesium-map
        • index.d.ts
        • cesium-china__cesium-map-test.ts
        • package.json
        • tsconfig.json
        • .npmignore
  • index.d.ts

    类型声明文件。所有的类型声明都应该在该文件中得到定义或者被导入。

  • cesium-china__cesium-map-test.ts

    单元测试文件,你应该在其中编写类型测试。(实测只要能通过编译就行)

  • package.json

    包含该包的元数据,包括其名称、版本和依赖关系。需要注意的是,其version字段应该始终以9999为结尾,如1.0.9999

  • tsconfig.json

    此文件允许你在软件包中运行tsc

  • .npmignore

    指定哪些文件应包含在包中。

3 正确处理外部依赖

我在外部依赖这方面踩了很多坑,因此不得不单独拿出来一部分来说明。

正如我的包名所言,其依赖于外部包Cesium中已经定义的类型。

因此我需要将其添加进/types/cesium-china__cesium-map/package.jsondependencies中。

但是这样是无法通过后续的单元测试的,因为Cesium这个包并不在允许的外部依赖项列表中。

因此你需要向microsoft/DefinitelyTyped-tools这个仓库提交 PR,将Cesium添加进这个文件中。

审核完成后,该依赖项就会被允许,从而通过单元测试。

4 单元测试与格式化代码

在完成所有类型声明的编写后,需要进行单元测试,而后格式化代码。

回到DifinitelyTyped项目根目录下,安装项目及你的包所需的依赖。

pnpm install -w --filter "{./types/cesium-china__cesium-map}..."

注意

注意不能直接执行pnpm install,这会把这个仓库的依赖全部安装!

然后进行单元测试:

pnpm test @cesium-china/cesium-map

测试结果会告知你是否通过,如果没有通过,会一并告知你原因。

单元测试通过后,还需要格式化代码。

pnpm dprint fmt -- '/types/cesium-china__cesium-map/*.ts'

这一步务必要执行,因为 DefinitelyTyped 十分严格,否则过不了 CI。

通过单元测试并格式化代码后,将你的代码 push 至远程仓库,准备提交 PR。

5 提交 PR、Code Review 与合并

提交 PR,会要求填写一份清单,按实际情况填写后提交即可。

然后 Github Actions 会自动运行 CI,没有问题的话,代码就会等待 Review,再之后就可以被合并进主分支。若 CI 未通过,则需要修复错误后重新提交。

代码完成合并的一到两个小时之内就会被发布到 npm 上。

此时即可使用npm install --save @types/cesium-china__cesium-map来为@cesium-china/cesium-map启用类型支持。

6 致谢

再次为所有开源项目开发者、维护者、贡献者致以最诚恳的敬意。

Copyright ©️ 2024 - 2025 YOAKE | Powered by VuePress & Plume
冀 ICP 备 2025102465号-1 · 京公网安备 11011502038573 号