π Search Terms
"arrow function", "optional chaining", "comment", "return undefined", "ASI", "downlevel emit"
π Version & Regression Information
- This changed between versions 6.0.3 and 7.0.2
β― Playground Link
No response
π» Code
const before: { color?: { text: string } } = {
color: { text: "black" },
};
const after: { color?: { text: string } } = {
color: { text: "white" },
};
const changed = () =>
// Compare the colors.
before.color?.text !== after.color?.text;
console.log(changed());
Compiler options
{
"compilerOptions": {
"target": "es2019",
"module": "commonjs"
}
}
π Actual behavior
TypeScript 7.0.2 emits:
const changed = () => {
var _a, _b;
return
// Compare the colors.
((_a = before.color) === null || _a === void 0
? void 0
: _a.text) !==
((_b = after.color) === null || _b === void 0
? void 0
: _b.text);
};
Due to JavaScript automatic semicolon insertion, the generated function is equivalent to:
const changed = () => {
return;
};
Runtime output:
undefined
The comparison is never evaluated.
π Expected behavior
The generated return statement should contain the transformed expression.
TypeScript 6.0.3 emits code equivalent to:
const changed = () => {
var _a, _b;
// Compare the colors.
return ((_a = before.color) === null || _a === void 0
? void 0
: _a.text) !==
((_b = after.color) === null || _b === void 0
? void 0
: _b.text);
};
Runtime output:
true
Additional information about the issue
Reproduction commands
TypeScript 7:
npx -p typescript@7.0.2 tsc repro.ts \
--ignoreConfig \
--target es2019 \
--module commonjs
node repro.js
Output:
undefined
TypeScript 6:
npx -p typescript@6.0.3 tsc repro.ts \
--ignoreConfig \
--target es2019 \
--module commonjs
node repro.js
Output:
true
The issue appears when all of the following are present:
- An arrow function uses a concise expression body.
- A comment appears immediately after =>.
- The expression requires downlevel transformation, such as optional chaining when targeting ES2019.
- The emitter converts the arrow body into a block and synthesizes a return.
- The comment is emitted after the synthesized return, separated by a newline, which changes the runtime semantics due to automatic semicolon insertion.
Known workarounds:
- Use an explicit block and return (...).
- Move the comment before the arrow function declaration.
- Remove the comment.
- Target ES2020 or newer so optional chaining is not downleveled.
- Compile with TypeScript 6.
π Search Terms
"arrow function", "optional chaining", "comment", "return undefined", "ASI", "downlevel emit"
π Version & Regression Information
β― Playground Link
No response
π» Code
Compiler options
{ "compilerOptions": { "target": "es2019", "module": "commonjs" } }π Actual behavior
TypeScript 7.0.2 emits:
Due to JavaScript automatic semicolon insertion, the generated function is equivalent to:
Runtime output:
undefinedThe comparison is never evaluated.
π Expected behavior
The generated return statement should contain the transformed expression.
TypeScript 6.0.3 emits code equivalent to:
Runtime output:
trueAdditional information about the issue
Reproduction commands
TypeScript 7:
Output:
trueThe issue appears when all of the following are present:
Known workarounds: