TypeScript 中的 importsNotUsedAsValues(已废弃)

说明 importsNotUsedAsValues 曾经如何控制只用于类型的导入该如何 emit,以及它为什么已被 verbatimModuleSyntax 取代。

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

[!info] related notes

TypeScript 中的 importsNotUsedAsValues(已废弃)

一句话定义

importsNotUsedAsValues 是 TypeScript 3.8 引入的编译器选项(已废弃),提供 remove / preserve / error 三种模式来控制仅用于类型的导入在编译输出中应被删除、保留还是报错。

当前状态

TypeScript 官方 TSConfig 文档明确标注:

  • Deprecated in favor of verbatimModuleSyntax

新项目应直接使用 import type + verbatimModuleSyntax

核心机制 / 工作原理

三种模式

模式行为
remove(默认)删除所有仅用于类型的导入
preserve保留所有导入,即使它们只用于类型
error对仅用于类型的导入报错,强制使用 import type

实际代码示例

// tsconfig.json
{
  "compilerOptions": {
    "importsNotUsedAsValues": "error"
  }
}
// input.ts
import { UserData } from './types';  // UserData 只用于类型位置

// 模式 "remove"(默认)
// 编译输出:该行被删除

// 模式 "preserve"
// 编译输出:import { UserData } from './types'; 保留

// 模式 "error"
// 编译报错:请改为 import type { UserData } from './types';

与 preserveValueImports 的区别

维度importsNotUsedAsValuespreserveValueImports
控制粒度三种模式可选只有 true/false
侧重点”只用于类型的导入”怎么处理”看似未使用的值导入”要不要保留
推荐替代verbatimModuleSyntaxverbatimModuleSyntax

两者语义有交集但不完全相同,都被 verbatimModuleSyntax 统一取代。

为什么废弃

TypeScript 团队认为:

  1. 两个旧选项(importsNotUsedAsValuespreserveValueImports)语义重叠,容易混淆
  2. verbatimModuleSyntax 提供了更清晰的模型:你写什么 import,输出就保留什么
  3. import type 的配合更自然:显式标注类型导入,编译器不再需要猜测

迁移方式

  // tsconfig.json
  {
    "compilerOptions": {
-     "importsNotUsedAsValues": "error"
+     "verbatimModuleSyntax": true
    }
  }

迁移后:

  • 原来用 import type 的继续用
  • 原来用普通 import 但只用于类型的,改为 import type
  • 编译器会直接报错提示你修改,而不是静默删除

边界与常见误解

  • "preserve" 不是好选择:它会导致无用导入保留在 JS 输出中,增大 bundle 体积
  • "error" 是最严格的模式:它强制开发者显式区分值导入和类型导入,是最推荐的旧模式
  • 不等于 verbatimModuleSyntax:新选项的语义更广,还处理了 export type 等场景
  • 不解决模块格式问题:它只控制导入的删除/保留,不处理 CJS/ESM 转换

参考信息

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