如何配置Jest测试专属的全局TypeScript类型(@types/jest)使其不影响业务代码
遇到过一模一样的坑!业务里的自定义fail函数被Jest的全局类型悄悄覆盖,忘导入时TypeScript完全不报错,运行时直接崩溃,简直让人头大。下面分享几个我亲测有效的解决方案,按需选就行:
方案一:拆分TypeScript配置,彻底隔离业务与测试类型环境
这是最清晰、最推荐的做法,把业务代码和测试代码的TS配置分开,让@types/jest只在测试环境生效。
先修改主项目的
tsconfig.json:- 确保
types字段只包含业务需要的类型,不要加jest - 通过
exclude把测试文件排除在外,避免测试类型污染业务代码
{ "compilerOptions": { "target": "ESNext", "module": "ESNext", "types": ["node"] // 只放业务需要的全局类型,比如node }, "exclude": ["node_modules", "**/*.test.ts", "**/*.spec.ts"] }- 确保
新建测试专用的
tsconfig.test.json,继承主配置并引入Jest类型:{ "extends": "./tsconfig.json", "compilerOptions": { "types": ["jest"] // 只在测试环境加载Jest的全局类型 }, "include": ["**/*.test.ts", "**/*.spec.ts"] }最后在Jest配置文件(
jest.config.js)里指定使用这个测试配置:module.exports = { preset: 'ts-jest', testEnvironment: 'node', globals: { 'ts-jest': { tsconfig: 'tsconfig.test.json' } } };
这样一来,业务代码完全看不到Jest的全局类型,忘导入自定义fail时TypeScript会直接提示“fail未定义”的错误,从根源上避免混淆。
方案二:在业务代码中覆盖全局fail类型
如果不想拆分TS配置,可以在业务代码的全局类型定义里把Jest的fail覆盖掉,强制TS报错。
在项目的业务代码目录下新建一个global.d.ts文件(比如src/global.d.ts),写入:
declare global { // 把全局fail设为never,只要未导入自定义fail就会触发TS错误 const fail: never; } export {};
记得确保这个d.ts文件被主tsconfig.json的include字段包含(比如include: ["src/**/*"]),这样业务代码里只要没导入自己的fail就用的话,TS会直接报错,不会再把它识别成Jest的全局函数。
方案三:禁用Jest的全局fail函数
如果你能接受修改测试代码的写法,可以直接让Jest不把fail注入全局,改用expect.fail()代替。
在jest.config.js里添加配置:
module.exports = { // ...其他配置 globals: { fail: undefined // 禁用Jest的全局fail函数 } };
之后测试代码里需要用fail的地方,改成expect.fail('测试失败原因'),这样业务代码的全局类型里就不会有Jest的fail了,忘导入自定义fail时TS会正常报错。
备注:内容来源于stack exchange,提问作者Pierre Poupin

