如何修复导入类为类型时TypeScript ReferenceError类未定义错误
import type 是 TypeScript 提供的仅类型导入语法,所有通过该语法导入的内容仅会在静态类型检查阶段生效,编译为 JavaScript 时会被完全擦除,不会出现在最终运行的代码中。
你导出的 Car 是 ES6 类,它同时具备两个属性:
- 可作为类型使用:比如用来标注变量类型
const car: Car = {} - 可作为运行时值使用:比如用来实例化
new Car()、作为普通值传递
当你用 import type 导入 Car 后,如果代码中存在运行时使用 Car 的逻辑,编译后导入语句被擦除,自然就会触发 ReferenceError: Car is not defined 报错。
场景1:当前文件需要在运行时使用 Car
直接使用普通导入写法即可,该写法完全符合 @typescript-eslint/consistent-type-imports 规则要求(规则仅要求纯类型用途的导入用 import type,运行时用到的导入用普通写法不会触发规则报错):
import { Car } from './models'
如果你的项目用到了带元数据的装饰器(比如 NestJS、TypeORM 相关装饰器),装饰器会把类型标注转换为运行时元数据,这种场景下即使你看起来只用到了 Car 做类型标注,也需要用普通导入,否则元数据读取时会找不到 Car。
场景2:当前文件仅用 Car 做类型标注,无任何运行时使用
保持 import type { Car } from './models' 写法即可,不会触发报错。如果仍然报错,可在 .eslintrc 规则配置中补充如下配置,保证规则识别纯类型使用场景:
{ "rules": { "@typescript-eslint/consistent-type-imports": ["error", { "prefer": "type-imports", "disallowTypeAnnotations": false }] } }
可选优化:混合导入写法
如果同一个导入源里你既需要导入运行时值,也需要导入类型,可合并为一行写法(该语法需要 TypeScript 4.5 及以上版本支持,你当前使用的 4.4.2 版本需要先升级 TypeScript 才能使用):
// 示例:导入运行时值 Car,同时导入纯类型 User import { Car, type User } from './models'
内容的提问来源于stack exchange,提问作者Desmoline Awa

