如何解决TS2451错误:无法重新声明块级作用域变量'sum'
Jest + TypeScript 求和测试报错解决方案
我正尝试搭建Jest并运行一个简单的求和测试(示例来自jestjs.io)。
现有代码
sum.ts
function sum(a: any, b: any): any { return a + b; } module.exports = sum;
初始sum.test.ts
const sum = require('./sum'); test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });
第一个错误及解决
执行yarn test后控制台报错:
yarn test yarn run v1.22.17 warning ../../../package.json: No license field $ jest FAIL src/sum.test.ts ● Test suite failed to run src/sum.test.ts:1:7 - error TS2451: Cannot redeclare block-scoped variable 'sum'. 1 const sum = require('./sum'); ~~~ src/sum.ts:1:10 1 function sum(a: any, b: any) { ~~~ 'sum' was also declared here. Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 0.87 s Ran all test suites. error Command failed with exit code 1.
错误原因:TypeScript默认将未规范使用模块语法的文件视为全局脚本,sum.ts里的function sum会被当作全局变量,测试文件中通过require声明的sum变量与之重名,引发冲突。
修改导入后的第二个错误及解决
将sum.test.ts改为ES模块风格导入后:
import { sum } from './sum' test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });
执行yarn test又报错:
yarn test yarn run v1.22.17 warning ../../../package.json: No license field $ jest FAIL src/sum.test.ts ● Test suite failed to run src/sum.test.ts:1:21 - error TS2306: File '/Users/pasmo/Code/sandbox/.../src/sum.ts' is not a module. 1 import { sum } from './sum' ~~~~~~~ Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 0.812 s Ran all test suites. error Command failed with exit code 1.
错误原因:sum.ts用CommonJS的module.exports = sum导出单个值,而ES模块的import { sum }是解构导入,两者语法不匹配;同时TypeScript因文件导出方式不规范,未将其识别为模块。
最终解决方案
方案1:统一使用ES模块语法(推荐)
修改sum.ts为ES模块导出:
export function sum(a: any, b: any): any { return a + b; }
测试文件保持ES模块导入:
import { sum } from './sum'; test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });
同时确保tsconfig.json配置正确的模块选项:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "node" // 其他必要配置(如target、outDir等) } }
方案2:保持CommonJS语法并避免变量冲突
若坚持使用CommonJS,修改测试文件变量名避开重名:
const sumFunc = require('./sum'); test('adds 1 + 2 to equal 3', () => { expect(sumFunc(1, 2)).toBe(3); });
或在sum.ts中用立即执行函数包裹,避免函数暴露为全局变量:
module.exports = (function() { function sum(a: any, b: any): any { return a + b; } return sum; })();
内容的提问来源于stack exchange,提问作者track_p54skate
相关产品推荐
相关产品推荐

