首页 / TypeScript 入门教程 / @types 与 DefinitelyTyped

TypeScript 入门教程

@types 与 DefinitelyTyped

本教程共 80 篇 · 第 65 篇 · 更新于 2026-08-10 · 约 13 分钟阅读

TypeScriptTypeScript 入门教程@typesDefinitelyTyped类型定义npm开源贡献

本节目标:了解 @types 包体系的全貌——它从哪来、怎么用、版本号为什么那样定,以及如何向 DefinitelyTyped 社区贡献类型定义。学完你再遇到缺少类型的 npm 包,就知道怎么找、怎么装,甚至怎么给社区提交。

没有 @types 之前的世界

早年写 TypeScript,最头疼的不是类型系统,而是「第三方库没类型」。比如你装了个 lodash,然后写:

import _ from "lodash";
// TypeScript:找不到模块"lodash"的声明文件。

那时候你得自己满世界找声明文件——有人放在 GitHub 仓库里,有人放在博客上,版本还对不上。更糟糕的是,同一个库可能有五六个人各写了一套互不兼容的声明,你选哪套都踩坑。

DefinitelyTyped 就是来解决这个问题的。

DefinitelyTyped 是什么

DefinitelyTyped(简称 DT)是一个社区维护的类型定义仓库,托管在 GitHub 上:

https://github.com/DefinitelyTyped/DefinitelyTyped

它是 GitHub 上最大的仓库之一,包含了超过 8000 个 npm 包的 TypeScript 类型定义。任何 npm 上流行但没有自带类型的 JS 库,你大概率能在这里找到对应的 @types/xxx 声明包。

社区的工作流大概是这样:

  1. 有人给一个没类型的 npm 包写了声明文件。
  2. 提交 Pull Request 到 DefinitelyTyped 仓库。
  3. DT 的维护者 review 后合并。
  4. 自动化工具(types-publisher)把声明文件打包发布到 npm 的 @types 组织下。

所以你在 npm 上看到的 @types/react@types/lodash@types/node,它们的源头都是 DefinitelyTyped 仓库里的一个 PR。

安装 @types 包

安装方式就是普通的 npm 命令:

npm install --save-dev @types/lodash

装好之后,在 TypeScript 项目中就能直接用了:

import _ from "lodash";

_.padStart("Hello", 10, "-");
// TS 知道 padStart 接收三个参数,返回 string
Note

TS 7.0 的默认 types: [] 意味着安装 @types/xxx 之后,你还需要在 tsconfig.jsontypes 数组里显式声明它。不像 TS 6.x 及以前,装了就自动加载。

tsconfig.json 里启用:

{
  "compilerOptions": {
    "strict": true,
    "types": ["node", "lodash"]
  }
}

或者干脆不走 types 字段,而是通过 import 让 TS 自动解析——对于模块库的声明文件,import 语句本身就触发了类型加载。

@types 的版本号规则

@types 包的版本号遵循一条简单的规则:包名和版本号都与它对应的 npm 包保持一致

@types/lodash 为例:

lodash 的版本:4.17.21
@types/lodash 的版本:4.17.21(或类似)

版本的 major.minor 要跟源包对齐,patch 版本可以独立变化(因为类型定义修改了不影响运行时)。举个例子:

lodash 版本@types/lodash 版本含义
4.17.21@types/lodash@4.17.21类型定义了 lodash 4.17.x 的 API
3.10.1@types/lodash@3.10.1类型定义了 lodash 3.10.x 的 API

如果 lodash 发布了 5.0.0,API 发生了破坏性变更,@types/lodash 也需要跟着升级到 5.0.x。版本号对齐是 DT 的类型正确性保证

Tip

如果你升级了一个 npm 包,记得同时检查 @types/xxx 的版本是否匹配。版本不对齐最常见的表现是:某个方法突然类型不对了,或者新 API 完全没有类型提示。

如何查找类型定义

有两个方式:

方式一:npm 直接搜索

npm search @types/lodash

方式二:微软的类型搜索工具

访问 TypeScript 官方的类型搜索页面:

https://www.typescriptlang.org/dt/search

输入包名,它会告诉你:

  • 是否有对应的 @types/xxx
  • 如果没有,这个包是否自带类型(bundled types)
  • 最新版本和更新时间

另外,npm 包的页面右上角有一个 TypeScript 图标:蓝色六边形表示包自带类型,灰色六边形表示类型在 DT 上。

包自带的类型 vs @types

有些包把 .d.ts 文件直接打包在 npm 包里,不需要额外安装 @types。这类包的 package.json 会有 "types""typings" 字段:

{
  "name": "some-library",
  "version": "2.0.0",
  "main": "./lib/index.js",
  "types": "./lib/index.d.ts"
}

典型例子:date-fnsimmerzod

如果一个包自带类型,你不需要也千万不要同时安装 @types/xxx——自带的类型和 DT 的类型可能冲突。

怎么区分?看 npm 包页面或 package.json 的 types 字段。有 types 的就是自带,没有的就去 DT 找。

贡献类型定义

假设你用的一个 npm 包既没有自带类型,DT 上也没有。你可以自己写一套声明然后提交给 DefinitelyTyped。

大致的贡献流程:

1. Fork DefinitelyTyped 仓库

https://github.com/DefinitelyTyped/DefinitelyTyped

2. 创建你的类型包目录

mkdir types/my-awesome-lib

3. 写声明文件

至少需要一个 index.d.ts

// types/my-awesome-lib/index.d.ts
export function greet(name: string): string;
export function farewell(name: string): string;

4. 写 tsconfig.json

{
  "compilerOptions": {
    "module": "node16",
    "lib": ["es6"],
    "noImplicitAny": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true
  },
  "files": ["index.d.ts"]
}

5. 写测试文件

DT 要求每个类型包都有对应的测试文件(my-awesome-lib-tests.ts):

import { greet, farewell } from "my-awesome-lib";

const msg: string = greet("TypeScript"); // 类型正确就应该编译通过
farewell("TypeScript");

测试文件不需要实际运行,只需要 tsc 编译通过即可——它验证的是你的类型定义在使用方式上的正确性。

6. 提交 Pull Request

Push 到你的 Fork 之后,在 GitHub 上提交 PR。DT 的 CI 会自动运行类型检查。维护者 review 通过后合并,你的类型包就会通过自动化流水线发布到 npm 的 @types/my-awesome-lib

Note

DT 对声明文件的质量有一定要求:不能用 any 偷懒、回调函数返回类型应该用 void 而不是 any、不要用 /// <reference path="..." /> 而用 /// <reference types="..." />。建议提交前先读一遍 DT 的贡献指南。

DT 社区现状

DefinitelyTyped 目前有超过 8000 个类型包,活跃的维护者数百人。它是 TypeScript 生态中仅次于编译器本身的最大基础设施。

几个数字:

  • 每周 npm 下载量超过 1 亿次的 @types/node
  • React 的类型定义在 @types/react(虽然 React 本身是 TS 写的,但类型定义量巨大,仍通过 DT 管理)
  • 几乎所有知名的 JS 工具链、数据库驱动、测试框架都在 DT 上有类型定义

社区维护方式的优势是覆盖面广、响应快。一个 npm 包发布一两周后,通常就有志愿者把类型定义提上去。它的劣势是质量参差——有些包的类型非常精确,有些只覆盖了主 API,边缘用法可能类型不全。

总结

  • @types/xxx 是 DefinitelyTyped 社区维护的类型定义包。
  • 安装方式:npm install --save-dev @types/xxx
  • 版本号跟源包对齐(major.minor 一致),patch 可独立。
  • 包自带类型(有 "types" 字段)就不要再装 @types
  • 你可以给没类型的包写声明文件,通过 PR 提交到 DT 仓库回馈社区。
  • TS 7.0 需要显式在 types 字段声明使用的类型包。

下一章是这个系列的最后一章——不写 .d.ts 也能享受类型安全?没错,通过 JSDoc 注解和 tsc --declaration,你可以在纯 JS 项目里渐进地引入类型。