TypeScript类型检查时加载并列出node_modules中d.ts文件的疑问
TypeScript类型检查时加载并列出node_modules中d.ts文件的疑问
我最近在调试一个简单的TypeScript项目时,遇到了一个关于TypeScript类型检查时文件加载的疑问,整理了相关信息跟大家探讨:
项目背景
先给大家看看我的项目目录结构:
├── package-lock.json ├── package.json ├── src │ ├── add.ts │ ├── index.ts │ ├── multiply.ts │ ├── sub.ts │ ├── version.ts │ └── vite-env.d.ts ├── tsconfig.json └── vite.config.ts
我通过tsc --noEmit --showConfig查看最终生效的TS配置,发现files数组里只有6个源码文件,符合预期:
{ "compilerOptions": { "target": "es2020", "useDefineForClassFields": true, "module": "esnext", "lib": [ "es2020", "dom", "dom.iterable" ], "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "isolatedModules": true, "allowSyntheticDefaultImports": true, "resolvePackageJsonExports": true, "resolvePackageJsonImports": true, "resolveJsonModule": true, "preserveConstEnums": true, "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictBindCallApply": true, "strictPropertyInitialization": true, "strictBuiltinIteratorReturn": true, "alwaysStrict": true, "useUnknownInCatchVariables": true }, "files": [ "./src/add.ts", "./src/index.ts", "./src/multiply.ts", "./src/sub.ts", "./src/version.ts", "./src/vite-env.d.ts" ], "include": [ "src" ] }
但当我运行tsc --extendedDiagnostics --noEmit时,发现Files计数是61,远大于我的6个源码文件:
Files: 61 Lines of Library: 39992 Lines of Definitions: 1368 Lines of TypeScript: 23 Lines of JavaScript: 0 Lines of JSON: 0 Lines of Other: 0 Identifiers: 45771 Symbols: 30218 Types: 98 Instantiations: 0 Memory used: 57623K Assignability cache size: 0 Identity cache size: 0 Subtype cache size: 0 Strict subtype cache size: 0 I/O Read time: 0.03s Parse time: 0.08s ResolveModule time: 0.00s ResolveTypeReference time: 0.01s ResolveLibrary time: 0.01s Program time: 0.14s Bind time: 0.04s Check time: 0.01s printTime time: 0.00s Emit time: 0.00s Total time: 0.19s
再运行tsc --noEmit --listFiles,发现输出里包含了大量node_modules/typescript/lib/下的.d.ts文件(比如lib.es5.d.ts、lib.dom.d.ts等),这让我一开始有点困惑,后来查了资料才明白这是正常行为,跟大家解释下:
核心原因:TypeScript的标准类型库
这些从node_modules/typescript/lib/加载的.d.ts文件,是TypeScript自带的标准类型库定义文件,它们的作用非常关键:
- 描述语言与环境类型:这些文件用来定义JavaScript语言本身(比如
Array、Promise、Map等内置对象)以及浏览器DOM环境(比如window、document、HTMLElement等)的类型信息。没有这些定义,TypeScript无法识别全局对象的类型,你的代码里使用Promise或者document.getElementById都会报类型错误。 - 自动加载逻辑:TypeScript会根据你
tsconfig.json里的lib配置项,自动加载对应的标准库文件。比如你配置了lib: ["es2020", "dom", "dom.iterable"],TypeScript就会加载所有与ES2020标准、DOM API相关的类型定义文件。 - 为什么出现在文件列表里:
tsc --listFiles会列出TypeScript在类型检查/编译过程中所有参与处理的文件,包括你的源码、引入的第三方模块,以及自动加载的标准库定义,这是正常的,不是问题。
几个关键命令的区别
为了更清楚,我整理了几个命令的差异:
tsc --noEmit --showConfig:输出的files数组只包含你自己的源码文件(通过files、include配置匹配到的),不会包含TypeScript自动注入的标准库文件。tsc --noEmit --listFiles:输出所有参与类型检查的文件,包括源码、第三方模块类型、标准库类型定义,所以会看到大量node_modules/typescript/lib/下的文件。tsc --extendedDiagnostics --noEmit:统计的Files总数是所有参与处理的文件数量,也就是你的源码数 + 标准库文件数 + 其他参与的类型文件数,所以会远大于你的源码数量。
验证小技巧
如果你想直观感受这些标准库的作用,可以临时把tsconfig.json里的lib配置改成空数组:
"lib": []
然后再运行tsc --noEmit,你会发现代码里所有用到全局对象的地方(比如console.log、Promise)都会报找不到名称 'XXX'的错误,同时tsc --listFiles的输出里也会少掉那些标准库.d.ts文件。验证完记得改回原来的配置哦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

