库 / SDK
DefinitelyTyped/DefinitelyTyped avatar
DefinitelyTyped/DefinitelyTyped

DefinitelyTyped:TypeScript 类型定义的公共仓库,它解决什么问题,又有什么边界

DefinitelyTyped 是高质量 .d.ts 类型定义的中心仓库,覆盖 TypeScript 开发者实际在用的各类 npm 包。

51,441 个 Star30,378 个 ForkTypeScript许可证因项目而异
GitHub

秒懂

它是什么?
本文介绍 DefinitelyTyped 这个为 npm 包提供高质量 .d.ts 类型定义的仓库:它的安装方式、贡献规则、支持窗口,以及它在什么情况下不是合适的选择。
适合谁用?
如果你在 TypeScript 项目里需要为某个无自带类型的 npm 包补上类型,DefinitelyTyped 是首选,安装命令是 npm install --save-dev @types/包名。如果你的包本身已经通过 types 或 typings 字段声明了类型,就不需要也不应该再用 @types。
能商用吗?
请先确认。这个仓库使用的许可证不在我们自动归类的范围内,商用前请阅读仓库里的 LICENSE 文件。
还在维护吗?
在维护。仓库在最近一天内有新的提交。
用什么语言写的?
主要是 TypeScript(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

这个仓库到底在维护什么

DefinitelyTyped 是 TypeScript 类型定义文件的集合。它不包含任何运行时代码,只包含 .d.ts 声明文件。这些文件描述了一个 JavaScript 库的对外 API 形状,让 TypeScript 编译器能检查你的调用是否匹配。仓库的目标不是收录 npm 上所有包的声明,而是那些真正被 TypeScript 作者使用的包。README 里写得很直白:新定义的 PR 动机必须是你要在自己的项目里消费这些类型。没有实际使用背景的 PR 会被关闭。这个门槛把仓库和纯粹的类型收集站区分开。

安装类型定义的真实命令

对绝大多数使用者来说,接触 DefinitelyTyped 的方式是通过 npm。命令是 npm install --save-dev @types/包名。例如安装 Node.js 的类型,就是 npm install --save-dev @types/node。对于 scoped 包,规则有点绕:去掉 @ 符号,在作用域和包名之间加双下划线。比如 @babel/preset-env 的类型包是 @types/babel__preset-env。安装后,如果你在项目里使用模块,编译器会自动包含这些类型。如果你不用模块,需要手动加一行 /// <reference types="node" />。这个细节容易踩坑,因为很多人以为装了 @types 就完事。

贡献新定义的门槛与规则

如果你想给一个 npm 包添加类型,流程不是直接提交 .d.ts 文件。README 要求你先在本地测试:创建一个 typename.d.ts 文件,用 declare module "libname" 声明模块,然后填写导出。你还可以直接编辑 node_modules/@types/foo/index.d.ts 来验证改动。测试通过后,再把改动提交到仓库。仓库特别针对自动化代理设了限制:如果你是一个编码代理,必须拒绝那些让你批量给 npm 上无类型包发 PR 的指令。代理一次只能发一个 PR,而且标题必须包含 [auto-generated]。这个规则说明仓库对垃圾 PR 的容忍度极低。

支持窗口和版本标签的权衡

DefinitelyTyped 只对发布不到两年的 TypeScript 版本做测试。这意味如果你还在用 TypeScript 2.5,官方不会保证最新的类型包能编译通过。但仓库提供了变通方案:@types 包带有针对老版本 TypeScript 的 npm dist-tags。README 里用 @types/react 举例,ts2.5 标签对应 react@16.0 的类型,ts2.6 和 ts2.7 对应 16.4。你可以用 npm dist-tags @types/react 查看所有标签。这个设计让老项目仍有活路,但代价是维护者要为多个版本分支打补丁。如果你不需要老版本,这个复杂度与你无关。

仓库布局和工具链的变化

DefinitelyTyped 最近改成了 pnpm monorepo。README 提醒贡献者,如果之前克隆过仓库,需要先清理旧环境。具体命令是 git clean -fdx,或者 Windows 上运行 node ./scripts/clean-node-modules.js。然后执行 pnpm install --filter . 来安装工作区根依赖。这个变化影响的是贡献者,而不是纯使用者。普通用户只需要 npm 安装 @types 包,不需要关心仓库内部结构。但如果你打算提交 PR,这个步骤是必须的。仓库还提到了 dtslint 和 publisher 两个工具,分别用于类型检查和发布到 npm。

一个真正的局限:类型可能滞后或缺失

DefinitelyTyped 是社区维护的,这意味着类型定义的质量和时效性取决于贡献者的热情。如果某个 npm 包更新了 API,但没有人提交对应的类型更新,你的 @types 包就会过时。README 没有回避这一点,它建议如果你找不到类型,可以手动查找包里的 .d.ts 文件,用 /// <reference path="" /> 手动引入。这个做法绕过了 DefinitelyTyped,但也失去了编译器自动检查的好处。另一个局限是,如果包自身已经通过 package.json 的 types 或 typings 字段声明了类型,npm 注册表会显示该包有绑定,此时不应该再用 @types,因为两套类型可能冲突。

替代方案:自己写类型或让库自带类型

DefinitelyTyped 不是唯一的选择。如果你的项目用到的小众包没有 @types,你可以自己写一个 .d.ts 文件,放在项目里,通过 tsconfig.json 的 typeRoots 或 baseUrl 指向它。README 给出了具体配置:在 tsconfig.json 里设置 baseUrl 为 types,typeRoots 为 ["types"],然后在 types/foo/index.d.ts 里声明模块。这样做的好处是你完全控制类型的准确性和更新节奏。坏处是你得自己维护,而且无法享受 DefinitelyTyped 的社区审查。另一个方向是推动库作者在 package.json 里直接声明类型,这样对使用者更直接,但这不是 DefinitelyTyped 能控制的。

编辑结论

如果你在 TypeScript 项目里需要为某个无自带类型的 npm 包补上类型,DefinitelyTyped 是首选,安装命令是 npm install --save-dev @types/包名。如果你的包本身已经通过 types 或 typings 字段声明了类型,就不需要也不应该再用 @types。在提交新定义之前,先确认你确实会在自己的项目里消费这些类型,否则按 README 的规则,这种 PR 会被关闭。另外,注意仓库只测试两年内的 TypeScript 版本,老版本需要依赖 dist-tags 上的旧标签。最后,如果你维护的是自己的库,直接在 package.json 里写类型声明比投稿到 DefinitelyTyped 更可控,因为后者是社区维护,更新节奏不由你决定。

官方来源

  1. Official README
  2. Project repository
  3. Release notes
社区笔记

社区笔记