TypeScript 中的 import type 与普通 import
说明 import type 与普通 import 的差异、编译后行为以及何时应该选择类型导入。
#dev
#typescript
#synthesis
#growing
[!info] related notes
- 所属 MOC: TypeScript MOC
- 总览页: TypeScript
- 并列概念: TypeScript 中的全局声明与全局扩展
- 相关配置: TypeScript 中的 verbatimModuleSyntax
- 速记入口: TypeScript 速记
TypeScript 中的 import type 与普通 import
一句话定义
import type 只导入类型信息,不保留运行时值;普通 import 既可以提供类型信息,也会把运行时依赖带进最终模块图。
核心机制 / 工作原理
普通 import
import { User } from "./user";
如果 User 是一个 class、函数或常量,这个导入在运行时也存在。
import type
import type { User } from "./user";
这种导入只在编译阶段存在,最终 JavaScript 中通常不会保留它。
最小例子 / 最小场景
只做类型注解
import type { User } from "./user";
const users: User[] = [];
需要运行时值
import { User } from "./user";
const user = new User();
什么时候该用哪种
优先用 import type
适合:
- 接口
- type alias
- DTO 类型
- 只做参数 / 返回值注解
必须用普通 import
适合:
- class 实例化
- 静态方法调用
instanceof- 运行时常量、函数、枚举值
边界与易混淆点
普通 import 也能被拿来做类型注解
普通 import 并不是“不能做类型”,而是它会把运行时依赖也带进来。
import type 不是性能银弹
它能让依赖边界更清楚,也能减少无意义的运行时导入,但真正的构建体积还要结合 bundler、tree-shaking 和模块结构一起看。
和 verbatimModuleSyntax 有关系
在较新的 TypeScript 配置里,import type 能让“哪些导入只用于类型”这件事更显式,也更利于和现代模块语义保持一致。
可以继续看:
学习检查
不看正文回答:
import type与普通import最根本的差异发生在类型空间还是运行时模块图?- 为什么只用于接口 / type alias 的符号适合
import type? - 一个 class 只被当作类型注解时可以怎样导入?如果要
new或instanceof呢? - 为什么
import type不是“自动减包体积”的性能银弹? verbatimModuleSyntax为什么让类型导入边界更值得显式表达?- 给一个 DTO 与一个运行时枚举,判断两者分别应该怎样导入。