TypeScript 中的 allowImportingTsExtensions

说明 allowImportingTsExtensions 为什么允许源码直接以 .ts/.tsx/.mts 扩展名互相导入,以及它为什么只允许在 noEmit 或 emitDeclarationOnly 场景下开启。

#tech / dev #resource / typescript #type / concept #status / growing

[!info] related notes

TypeScript 中的 allowImportingTsExtensions

一句话定义

allowImportingTsExtensions 允许 TypeScript 源文件直接用 .ts.mts.tsx 这类 TS 扩展名互相导入。

核心机制 / 工作原理

官方文档直接说明:

  • 它允许 TypeScript files to import each other with a TypeScript-specific extension

例如:

import { foo } from "./foo.ts";

这在默认配置下往往不是主流路径,但开启:

{
  "compilerOptions": {
    "allowImportingTsExtensions": true
  }
}

后,TypeScript 会接受这种写法。

最小例子 / 最小场景

官方文档同时给了一个非常重要的限制:

  • 这个选项只允许在 noEmitemitDeclarationOnly 开启时使用

原因也写得很清楚:

  • 否则这些 .ts 导入路径在最终 JavaScript 输出里无法在运行时解析

所以它更适合:

  • bundler / runtime 自己理解 .ts 扩展名
  • TypeScript 不直接产出可运行 JS

边界与易混淆点

它不是“普通 tsc emit 项目都能随便开”的选项

如果项目直接靠 tsc 生成 JS,再把产物交给运行时执行,那么 .ts 扩展名通常就会变成运行时问题。

它和 rewriteRelativeImportExtensions 关心的是相邻但不同的问题

  • allowImportingTsExtensions 讨论源码里能不能直接写 .ts
  • rewriteRelativeImportExtensions 讨论 emit 时这些扩展名要不要改写成 JS 版本

它默认假设还有别的 resolver 在兜底

官方文档明确写了:

  • 期望你的 bundler、runtime 或其他工具来让这些 .ts 导入真正工作

参考信息

创建于 2026/5/15 更新于 2026/5/27