解决ts-jest结合ES Modules在Jest中的TypeScript编译及测试错误
解决ts-jest搭配ES Modules的编译与测试错误
核心问题拆解
- 导入
import { jest } from '@jest/globals'时,npx tsc编译测试文件触发TS2345类型错误:jest.fn()默认返回never类型,无法匹配$queryRaw的参数类型。 - 不导入jest时,测试执行报错
ReferenceError: jest is not defined。
解决方案
方案1:给jest.fn()指定类型(保留导入)
显式让TypeScript识别jest.fn()的返回类型与PrismaClient['$queryRaw']匹配:
import { jest } from '@jest/globals'; import type { PrismaClient } from '@prisma/client'; describe("attribute-api", () => { describe("readme attribute", () => { it("returns true when readme exists", async () => { const mockDbClient = { // 绑定PrismaClient的$queryRaw类型 $queryRaw: jest.fn<PrismaClient['$queryRaw']>().mockResolvedValue([ { has_readme: true }, ]) }; const readme = await getAttributes(mockDbClient as PrismaClient, "sp-test", SupportedAttributes.ReadMe); expect(readme).toEqual({ has_readme: true }); }); }); });
也可以用类型断言简化:
$queryRaw: jest.fn().mockResolvedValue([{ has_readme: true }]) as PrismaClient['$queryRaw']
方案2:让jest全局可用(无需手动导入)
- 在
tsconfig.json的compilerOptions中添加jest类型,让TypeScript识别全局jest变量:
{ "compilerOptions": { // ...其他配置 "types": ["jest"] } }
- 调整
jest.config.ts确保ESM模式下注入全局jest:
import type { JestConfigWithTsJest } from 'ts-jest' const jestConfig: JestConfigWithTsJest = { preset: 'ts-jest/presets/default-esm', extensionsToTreatAsEsm: ['.ts'], testEnvironment: "node", testPathIgnorePatterns: ["<rootDir>/dist"], moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', }, transform: { '^.+\\.tsx?$': [ 'ts-jest', { useESM: true, globals: { 'ts-jest': { useESM: true } } }, ], }, } export default jestConfig
此时测试代码可直接使用全局jest,无需导入,npx tsc编译也不会报错。
方案3:排除测试文件避免tsc编译
如果不需要tsc处理测试文件(测试由ts-jest单独处理),在tsconfig.json中添加排除规则:
{ "exclude": ["node_modules", "**/*.test.ts"] }
这样npx tsc只会编译业务代码,从根源避免测试文件的类型错误。
验证步骤
- 执行
npx tsc确认编译无错误。 - 执行
npx jest运行测试,确认无ReferenceError。
内容的提问来源于stack exchange,提问作者semural
相关产品推荐
相关产品推荐

