使用ts-jest时声明的namespace(.d.ts)测试报‘未定义’引用错误
解决ts-jest测试时
ReferenceError: R is not defined问题 问题背景
前端应用在浏览器中运行正常,但使用ts-jest执行TypeScript测试时,抛出ReferenceError: R is not defined错误。R是通过R.d.ts声明类型的全局JS库(对应api/r-api.js)。
问题原因
浏览器环境中r-api.js已被全局加载,因此R变量可直接访问;但jest测试环境不会自动加载该JS文件,而R.d.ts仅负责TypeScript编译时的类型检查,无法提供运行时的实际对象。
解决方案
方案1:在测试文件中导入实际JS库
直接在测试文件开头导入r-api.js,让jest加载该库:
// job.test.ts import '../api/r-api.js'; // 先加载实际的JS库 import { describe, expect, test } from '@jest/globals'; import Job from '../app/job' describe('Test Job',()=>{ test('job init',()=>{ let job = new Job() // 测试代码 }) })
方案2:全局引入JS库(避免重复导入)
修改jest.config.js,通过setupFiles配置让jest在所有测试执行前加载r-api.js:
/** @type {import('ts-jest').JestConfigWithTsJest} */ export default { preset: "ts-jest", testEnvironment: "jsdom", moduleDirectories: ["node_modules", "<rootDir>"], moduleNameMapper: { "^(\\.{1,2}/.*)\\.js$": "$1", }, transform: { "^.+\\.{ts|tsx}?$": [ "ts-jest", { allowJs: true, useESM: true, }, ], }, // 添加全局加载配置 setupFiles: ['<rootDir>/api/r-api.js'] };
方案3:Mock全局R对象(无需依赖库实际逻辑时使用)
如果测试不需要调用r-api.js的真实逻辑,可手动模拟全局R对象:
// job.test.ts import { describe, expect, test, jest } from '@jest/globals'; import Job from '../app/job' // 模拟全局R对象 global.R = { P: { getCMD: jest.fn(() => ({ /* 自定义模拟返回值 */ })) } } as typeof R; describe('Test Job',()=>{ test('job init',()=>{ let job = new Job() expect(R.P.getCMD).toHaveBeenCalled(); // 测试代码 }) })
额外说明
- 无需导入
.d.ts类型声明文件,TypeScript会自动识别tsconfig.json中配置的类型文件,你的现有tsconfig.json配置无问题。
内容的提问来源于stack exchange,提问作者forma
相关产品推荐
相关产品推荐

