lib属性用于显式声明TypeScript编译器需加载的全局类型定义(.d.ts),仅影响类型检查和编辑器提示,不改变运行时行为;它采用白名单机制,未列出的API即使代码中使用也会报错,常见组合如["es2020", "dom"]精准启用对应ES标准和DOM接口。

lib 属性的作用是告诉 TypeScript 编译器:哪些全局类型定义(.d.ts)需要被加载进类型检查环境,它不控制运行时行为,只影响类型识别和编辑器提示。
要精准控制代码中能用哪些 ECMAScript 特性和 DOM API,关键在于 显式声明 lib 数组,而不是依赖默认值。默认行为会根据 target 自动推导(比如 target: "es6" 会默认包含 ["ES6", "DOM", "DOM.Iterable", "ScriptHost"]),但这种隐式行为容易导致类型“意外可用”,不利于跨平台或精简环境开发。
✅ 明确指定 lib 值,避免隐式依赖
直接在 tsconfig.json 的 compilerOptions.lib 中写死所需库列表,例如:
{
"compilerOptions": {
"target": "es2020",
"lib": ["es2020", "dom"]
}
}这样就只启用 ES2020 标准的内置对象(如 Promise.allSettled、globalThis、BigInt)和浏览器 DOM 接口(document、Element、fetch 等),不会自动包含 es2021 或 dom.iterable 中的新类型。
⚠️ 注意:
lib是“白名单”机制——只加载你列出的库,没写的就不会参与类型检查。即使代码里写了Array.prototype.at(),如果es2022没在lib里,TS 就会报错。
? 常见组合与适用场景
-
纯 Node.js 后端项目(无浏览器)
"lib": ["es2021", "scripthost"]
-
es2021提供replaceAll、Promise.any等 -
scripthost补充require、__dirname等 Node 全局变量类型 - ❌ 不加
dom,避免误用window或document
-
-
现代浏览器应用(支持 ES2020+,含 DOM + 迭代器)
"lib": ["es2020", "dom", "dom.iterable"]
-
dom.iterable让NodeList、HTMLCollection支持for...of和Array.from() -
es2020已包含nullish coalescing(??)和optional chaining(?.)的类型支持
-
-
Web Worker 环境
"lib": ["es2020", "webworker"]
-
webworker提供self、postMessage、WorkerGlobalScope等类型 - 不含
dom,防止误调用document
-
-
严格最小化(仅 ES5 兼容 + 手动 polyfill)
"lib": ["es5"]
- 只有
Object、Array、Date等基础类型 -
Promise、Map、fetch全部不可用(除非你自己提供.d.ts)
- 只有
? 如何确认某个 API 是否被包含?
查官方类型库源码最可靠:
TypeScript 内置类型定义放在 lib.*.d.ts 中,比如:
-
lib.es2020.d.ts→ 包含globalThis、Intl.DateTimeFormat.formatRange -
lib.dom.d.ts→ 包含document.querySelector、fetch、AbortController -
lib.dom.asynciterable.d.ts→ 已合并进lib.dom.d.ts(自 TS 6.0 起,仅作兼容保留)
你也可以在 VS Code 中把光标停在某个全局变量上(如 fetch),按 Ctrl+Click 跳转,看它来自哪个 .d.ts 文件,再反推需不需要加对应 lib。
? 常见误区提醒
-
lib不影响生成的 JS 代码,只影响类型检查 -
target控制输出语法(如是否转译async/await),lib控制你能“写什么” - 即使
target: "es5",你仍可设"lib": ["es2022", "dom"]—— 类型检查宽松,但运行时得靠 polyfill -
dom.iterable和dom.asynciterable在 TS 6.0+ 中仍是合法项,但实际内容已合并,留着不影响,删掉也无妨
不复杂但容易忽略


















