babel-proposal-decorators与typescript-decorator不兼容原因及jest-expo适配方案
问题分析与解决方案
差异产生的原因
ts-jest 依赖 TypeScript 官方编译器(tsc)处理代码,会完整保留 TypeScript 原生装饰器的元数据生成逻辑,包括 typeClassification 这类 TypeScript 特有的元数据字段。而 jest-expo 默认采用 Babel 转译,使用的 @babel/plugin-proposal-decorators 实现的是早期装饰器提案,和 TypeScript 原生装饰器的元数据生成逻辑完全不兼容——Babel 的装饰器插件不会生成 typeClassification 这类字段,仅能处理最基础的 reflect-metadata 信息,这直接导致依赖该元数据的 class-fixtures-factory 库无法正常工作。
调整 jest-expo 对齐 ts-jest 行为的方法
方法1:改用 ts-jest 作为转译器
修改 jest 配置,让 jest-expo 使用 ts-jest 替代 Babel 处理 TypeScript 文件,完全复用 TypeScript 原生的装饰器和元数据逻辑:
// jest.config.js module.exports = { preset: 'jest-expo', transform: { '^.+\\.tsx?$': 'ts-jest', }, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], };
同时安装必要依赖:
npm install --save-dev ts-jest @types/jest
方法2:配置 Babel 兼容 TypeScript 装饰器
如果必须保留 Babel 转译,需要调整 Babel 配置,让装饰器行为和 TypeScript 对齐,并补充元数据生成逻辑:
- 安装依赖插件:
npm install --save-dev @babel/plugin-proposal-decorators @babel/plugin-transform-typescript babel-plugin-transform-typescript-metadata
- 修改 Babel 配置文件:
// babel.config.js module.exports = function(api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ // 启用 TypeScript 兼容的装饰器模式 ['@babel/plugin-proposal-decorators', { legacy: false, decoratorsBeforeExport: true }], ['@babel/plugin-transform-typescript', { allowDeclareFields: true }], // 补充 TypeScript 元数据生成 'babel-plugin-transform-typescript-metadata', ], }; };
- 在测试入口文件(如
setup.ts)中导入元数据依赖:
import 'reflect-metadata';
快照测试兼容
完成上述配置后,class-fixtures-factory 即可在 jest-expo 环境中正常工作,快照测试可按常规流程编写,使用 toMatchSnapshot() 生成和校验快照即可,无需额外特殊配置。
内容的提问来源于stack exchange,提问作者tkowt
相关产品推荐
相关产品推荐

