真实原因是typescript esm模式下,.ts后缀导入需满足noemit或emitdeclarationonly前提,否则应省略后缀并确保构建产物路径匹配运行时解析要求。

报错 An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' 的真实原因
这不是路径写错了,也不是 VSCode 抽风——而是 TypeScript 编译器在 ESM 模式下发现你既想用 .ts 后缀导入,又没满足它的硬性启用条件。关键点在于:allowImportingTsExtensions 这个选项本身就被设计为「只读类型检查、不生成 JS」的辅助开关,它和 noEmit 或 emitDeclarationOnly 是强绑定的。
为什么加 "allowImportingTsExtensions": true 反而报更怪的错
因为编译器立刻抛出第二条错误:Option 'allowImportingTsExtensions' can only be used when either 'noEmit' or 'emitDeclarationOnly' is set。这说明你当前配置是常规构建模式(要生成 .js 文件),而该选项只允许出现在纯类型检查场景里:
-
noEmit: true→ 不输出任何文件,只做类型检查(适合 CI 阶段快速验类型) -
emitDeclarationOnly: true→ 只输出.d.ts,不碰.js(适合发布类型包) - 但你实际需要的是正常编译 + 正常运行 → 这俩都不是解法
真正该做的:删掉 .ts 后缀,且关掉 allowImportingTsExtensions
ESM 规范要求导入路径必须指向最终运行时存在的文件。Node.js ESM 加载器不会自动补 .ts,也不会识别源码路径——它只认构建产物(.js)。所以你的导入路径应该和 tsc 输出后的目录结构对齐,而不是源码结构:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
- 把
import { foo } from "./utils.ts"改成import { foo } from "./utils" - 确保
tsconfig.json中显式设"allowImportingTsExtensions": false(TypeScript 5.0+ 默认就是false,但很多脚手架继承了旧配置,把它设成了true) - 确认
outDir和rootDir配置合理,构建后./utils.js确实存在且路径可被 Node.js ESM 解析到
VSCode 里还报红?检查 TypeScript 版本和语言服务状态
即使 tsconfig 改对了,VSCode 仍可能沿用旧版 TS 语言服务缓存,导致错误提示残留:
- 右下角点击 TypeScript 版本号 → 选 Use Workspace Version
- 命令面板运行
Restart TS Server(不是重启窗口) - 打开开发者工具(
Developer: Toggle Developer Tools),看 Console 是否有Failed to load typescript - 如果项目含 Vue/React 等框架,确认用了对应官方扩展(如 Volar),而非已弃用的 Vetur 或旧版插件
这个错误本质是类型检查与运行时模块解析模型错位,不是语法问题。改后缀或开开关只是绕路,对齐 ESM 路径语义才是根治点。










