Jest无法识别TypeScript import type语句致单元测试报错如何解决
问题说明
近期monorepository(单体仓库)完成以下依赖版本升级:
- Nx 14.3.6
- Angular 14.0.3
- Jest 28.1.1
- TypeScript 4.7.4
升级后代码编译正常,但运行时出现大量emitDecoratorMetadata causes runtime errors by referencing type-only imports with namespaces类报错,ESLint同步检测到该类错误。
最初通过将所有类型、接口的导入语句从普通import替换为import type解决了运行时问题:替换后运行时错误消除,应用可正常运行;同时安装并启用eslint-plugin-import扩展修复了对应的ESLint报错。
但修复后单元测试出现异常:Jest无法识别import type语法,所有使用import type的类对应的单元测试均运行失败,报错信息为:
ReferenceError: Zyz is not defined
其中Zyz为被测类中通过import type导入的类型,示例代码如下:
// some-component.ts import type { Xyz } from '...'; // 业务逻辑省略
如果移除import type中的type关键字,单元测试可正常运行,但会重新触发之前的运行时错误,调整Babel配置暂未找到可行解法。
可落地解决步骤
- 优先替换TS测试文件的转译器:不要使用
babel-jest处理.ts/.tsx后缀的源码文件,Nx 14版本自带的@nrwl/jest预设搭配ts-jest可原生支持import type语法,转译阶段会自动擦除所有类型-only导入,不会残留运行时引用。 - 调整Jest配置:打开项目根目录及各子项目的
jest.config.js,确认transform规则匹配,核心配置参考如下:
module.exports = { // 其余配置保持原有逻辑 transform: { '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular' }, globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json', stringifyContentPathRegex: '\\.(html|svg)$', } } }
- 修正测试用TS配置:打开测试专用的
tsconfig.spec.json,将compilerOptions下的importsNotUsedAsValues设置为remove,该配置会让TS编译测试代码时自动移除所有仅作为类型使用的导入语句,从根源上避免残留类型引用导致的变量未定义错误。 - 若项目必须保留Babel处理部分JS逻辑,给Babel配置添加
@babel/plugin-transform-typescript插件,开启onlyRemoveTypeImports: true参数,插件会在Babel转译阶段自动擦除所有import type语句,不会将类型导入编译为运行时的require调用。 - 最后排查测试启动文件:确认
reflect-metadata在测试入口文件(通常为test-setup.ts)的最顶部引入,避免装饰器元数据解析逻辑在类型导入被擦除前执行。
内容的提问来源于stack exchange,提问作者johey
相关产品推荐
相关产品推荐

