模块系统与路径解析

选项名
默认值
说明

allowArbitraryExtensions

false

允许导入任意文件扩展名的模块(非标准扩展名),一般用于非 .ts.js 文件的导入。

allowImportingTsExtensions

false

允许在导入路径中包含 .ts 等 TypeScript 文件扩展名。

allowUmdGlobalAccess

false

允许访问 UMD 包中的全局变量(无需导入即可使用)。

baseUrl

undefined

配置模块导入的基准目录,用于相对路径模块导入的基准。

customConditions

undefined

用于条件导入时自定义条件名称数组,影响包的条件导入分支解析。

module

esnext

指定模块系统,如 commonjsamdesnextnode16 等,决定生成代码的模块格式。

moduleResolution

node (默认 module 不是 none) / classic (module: none)

指定模块解析策略,node 模拟 Node.js 解析模块,classic 是老的 TypeScript 解析方式。

moduleSuffixes

undefined

模块解析时,优先匹配指定后缀列表,用于支持多环境文件(比如 .native.ts.web.ts 等)。

noResolve

false

禁止模块解析,只进行语法检查,不生成输出文件。

paths

undefined

路径映射,用于为模块导入配置别名映射规则。

resolveJsonModule

false

允许导入 .json 文件并将其视为模块。

resolvePackageJsonExports

true

启用对 package.jsonexports 字段的解析。

resolvePackageJsonImports

true

启用对 package.jsonimports 字段的解析。

rewriteRelativeImportExtensions

[".js", ".jsx", ".ts", ".tsx"]

允许重写相对导入扩展名,如 .js 导入重写为 .ts

rootDir

undefined

输入文件的根目录,输出文件结构会相对于此目录进行保留。

rootDirs

undefined

多个根目录,用于合并多个源文件目录为虚拟根目录,常用于项目多源目录。

typeRoots

["node_modules/@types"]

指定包含类型声明包的目录列表。

types

undefined

指定要包含的类型包名称列表,默认包含所有 typeRoots 下的类型包。

baseUrl

baseUrl 用于设置解析裸模块导入路径(bare specifiers)时的基础目录。简单来说,它允许你写出更短、更干净的 import 路径,而不用写相对路径如 ../../../

使用前:没有设置 baseUrl,只能使用相对路径:

使用后:设置 "baseUrl": "./",可以这样写:

📌 特点

特性
说明

模块解析起点

baseUrl 所指定的目录开始查找模块。

优先级高于 node_modules

如果模块名在 baseUrl 下找到了,就不会去 node_modules 中找。

可与 paths 搭配使用

可搭配路径别名配置,提供更强的模块解析能力。

不再强制与 paths 搭配

自 TypeScript 4.1 起,使用 paths 不再必须设置 baseUrl

注意事项

  1. 只影响裸路径:只影响像 "hello/world" 这种非相对路径的模块导入。

  2. 不推荐单独使用:文档中提到这个功能最初是为 AMD 浏览器加载器设计的,如果你使用 Node.js 或 Webpack,推荐配合 paths 使用。

  3. 易与模块路径冲突:若你导入的路径名与某个 npm 包名相同,可能出现歧义(会优先使用 baseUrl 路径)。

推荐搭配 paths 使用

然后就能这样使用模块:

是否应该使用 baseUrl

建议

在大型项目

✅ 建议配合 paths 使用

纯 Node.js 项目

❌ 更建议使用 module-alias 或直接用 paths 替代 baseUrl

多层级嵌套项目

✅ 有利于避免 ../../../ 导入

仅为模块简化导入

✅ 建议使用,注意路径唯一性

rootDir

rootDir用来指定 TypeScript 源文件的逻辑根目录,决定了输出目录中源代码的目录结构。

当你设置了 outDir 时,TypeScript 会在输出目录中保留从 rootDir 开始的目录结构。

默认情况下,TypeScript 会自动推断 rootDir,值为所有非申明文件的最长公共路径。

如果你启用了 composite: true,则默认值为 tsconfig.json 所在的目录。

默认推断 rootDir 为 core

如果你手动设置 rootDir: "."

typeRoots

typeRoots 用于指定 TypeScript 在编译时 查找类型声明(.d.ts)文件的根目录,默认情况下,所有可见的 @types 包都会被自动包含进编译中。

如果你没有设置 typeRoots

  • TypeScript 会自动查找所有位于 node_modules/@types 下的类型包;

  • 查找会向上递归查找父级目录的 node_modules/@types 目录;

默认情况下,你可以直接使用 lodash 的类型定义(例如 import _ from "lodash"),无需额外配置。

当你设置了 typeRoots 选项后,只有这些目录中的类型声明包才会被包含进来,其他默认目录(如 node_modules/@types)将会被忽略。

此时编译器只会从这两个路径中加载类型定义:

  • ./typings

  • ./vendor/types

不再包括 ./node_modules/@types

📌 使用建议

需求/场景
建议

使用社区提供的类型(如 @types)

✅ 不设置 typeRoots,使用默认行为更方便

使用项目私有的类型声明

✅ 设置 typeRoots,配合放在指定文件夹里

想禁止从 node_modules/@types 自动加载

✅ 设置 typeRoots 且不包含该路径

要配合 types 字段指定具体包

typeRoots 是指定根目录,types 是指定名称

types

✅ 作用:精确指定需要包含的类型声明包(@types/\*

当你指定了 types 选项时,只有你列出的 @types 包才会被包含到全局类型作用域中。其他默认包含的类型将被忽略。

🧱 默认行为(未设置 types

如果你没有设置 types

  • TypeScript 默认会加载你项目路径下以及所有上层目录中的 node_modules/@types/* 下的类型包。

  • 例如,会自动包含:

设置 types 示例

在这个例子中,TypeScript 只会包含以下三个类型声明包:

不会自动包含其他 @types/* 类型(如 @types/lodash 等)。

🎯 types 的影响范围

功能
是否受影响
说明

全局类型注入

✅ 会被限制

例如 process (node)、expect (jest) 不再是全局变量

自动导入推荐

✅ 会减少

编辑器不会推荐未包含的类型包中的导入

import 导入的模块类型

❌ 不受影响

import moment from "moment" 仍然会从 @types/moment 加载类型(如果已安装)

⚠️ 非常重要:types 不会限制通过 import 使用的类型

即便你没在 types 中写 moment,下面代码依然有类型:

这是因为 import 时 TypeScript 会根据导入语句去 node_modules/momentpackage.jsontypes 字段 或 去 @types/moment 寻找声明。

types vs typeRoots

特性

types

typeRoots

控制范围

精确列出哪些 @types/* 包会加载

指定哪些目录下的所有类型声明包会被加载

精度

更精细,只加载指定的包

更粗略,目录下的所有包都加载

覆盖默认行为

搭配场景

限制全局类型污染、加速编译

使用自定义类型声明存放路径

✅ 使用建议

场景

是否推荐使用 types

你只需要用一小部分 @types/* 包(如仅 node

✅ 是

想避免 Jest、JSDOM、Cypress 的全局污染

✅ 是

不清楚项目使用了哪些类型包

❌ 否(保持默认行为即可)

typeRoots 搭配使用私有类型

✅ 可混用,但要注意路径和命名

这有帮助吗?