我有以下TypeScript代码:
const myMap = new Map([["name", 5]]);
for (const foo of myMap.values()) {
console.log(foo);
}当我在节点(v8.12.0)中直接运行这段代码时,它可以工作,并输出"5“到控制台。
如果我在Jest测试中运行完全相同的代码,它永远不会执行for循环的内容。它运行for条件,然后跳过循环,从来不实际枚举值。
为什么会这样呢?Jest是否使用了JS运行时(不是节点吗?)它不支持for..of而不支持迭代吗?
谢谢!
发布于 2020-01-04 06:53:46
经过很长时间的调查,我发现了真相。有关解决方案的重要背景信息:
for..of循环迭代Iterable集合。如果要将for..of与Iterable结合使用,则必须针对比ES5更新的对象或使用--downlevelIteration flag。--downlevelIteration不是打开的。考虑到所有这些,我发现ts-jest无法找到我的项目的tsconfig.json文件,因此它使用默认设置运行我的测试,这意味着以ES5为目标而不允许downlevelIteration,所以我在Iterable上的所有for..of循环都无法工作。它找不到我的tsconfig.json文件的原因是,我的jest.config.js文件位于另一个目录中(树的上层),而且即使我是从一个带有tsconfig.json文件的目录中运行jest,ts-jest并没有查看“当前”目录,而是查看了我为jest.config.js文件所指向的目录,该目录不包含tsconfig.json。
我的解决方案是稍微修改我的目录结构,并利用tsConfig选项 of ts--开玩笑地告诉它在哪里找到我的tsconfig.json文件,这使得tsconfig.json文件“神奇”地工作起来,因为我的tsconfig.json文件目标是es2018,后者支持Iterable上的for..of迭代。
我考虑过但很快被忽略的另一种解决方案是上述tsConfig设置的特性,即在jest配置中直接设置--downlevelIteration编译器选项。我选择不这么做是因为,虽然它会修复这个特定的问题,但它不会修复更大的问题,即Jest测试正在用与我的生产代码不同的标志编译我的TypeScript!正因为如此,只有当前的问题才会导致我的for..of循环痛苦。
一个快速的后记:我最终在这个问题上取得进展的方式是在ts-jest中偶然发现了诊断选项。一旦我将其设置为true,当我尝试运行测试时,会显示如下错误:
TypeScript diagnostics (customize using [jest-config].globals.ts-jest.diagnostics option): src/foo.ts:163:47 - error TS2569: Type 'Map<Guid, FooInfo>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
似乎TS编译器错误应该显示(并导致测试失败),而不管ts-jest“诊断”是否启用,但不要理会。
https://stackoverflow.com/questions/57516047
复制相似问题