Skip to content

Incorrect ES5 code emitted for closures in loops when noCheck is enabled #59262

@PhoebeSzmucer

Description

@PhoebeSzmucer

🔎 Search Terms

ES5, noCheck, loop, closures, transpilation, transpileModule

🕗 Version & Regression Information

This broke in either #57934 or #58364

⏯ Playground Link

https://www.typescriptlang.org/dev/bug-workbench/?target=1&noCheck=true#code/PTAEAEDsHsGEAsCmBjA1gLlAFwE4FdEAoECLAQxwHNEtNEBnAVmLHHvmgHcBRAWwEsshQsmiR6WUADNxoALygA2gF0A3ISnQcoABSjxkgG5kANgVDQpSgIwAaUACZ7AZnsAWZQEpQAb0KgA6XEAOgAHPHYdHW85AD5dH1BjM0RQAF9PT3U0kTEJUBwGPBNJBRl6YN4yUJ0ZeXiZaKzc8WgTRGCTaEodQvpirE8gA

💻 Code

// @noCheck: true
// @target: es5
// @showEmit

const fns = [];
for (const value of [1, 2, 3]) {
    fns.push(() => ({ value }));
}
const result = fns.map(fn => fn());
console.log(result)

🙁 Actual behavior

The following incorrect code is produced:

"use strict";
var fns = [];
for (var _i = 0, _a = [1, 2, 3]; _i < _a.length; _i++) {
    var value = _a[_i];
    fns.push(function () { return ({ value: value }); });
}
var result = fns.map(function (fn) { return fn(); });
console.log(result);

Which evaluates to this incorrect value: [{ value: 3 }, { value: 3 }, { value: 3 }]

🙂 Expected behavior

The following should be produced:

"use strict";
var fns = [];
var _loop_1 = function (value) {
    fns.push(function () { return ({ value: value }); });
};
for (var _i = 0, _a = [1, 2, 3]; _i < _a.length; _i++) {
    var value = _a[_i];
    _loop_1(value);
}
var result = fns.map(function (fn) { return fn(); });
console.log(result);

Which would evaluate to: [{ value: 1 }, { value: 2 }, { value: 3 }]

Additional information about the issue

transpileModule(ts, { compilerOptions: { target: ScriptTarget.ES5 } }) started producing incorrect code in TypeScript 5.5, since I believe noCheck: true is the default there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions