Repository navigation
[bug] Ternary + arrow function is not correctly parsed #16241
Description
Activity
j-oliveras commented
on Jun 3, 2017 ContributorMore actionsI have the same problem.
Using playground, the code:
var b = 0, c = 1, e = 2; var a = b ? (c): d => e;
Is transpiled to:
var b = 0, c = 1, e = 2; var a = b ? function (c) { return e; } : ;
With the errors:
Cannot find name 'd'.atd.
':' expected.at second semi-colon.As reference, using node console:
var b = 0, c = 1, e = 2; var a = b ? (c) : d => e; console.log(a);
outputs
[Function]Changing to
b = 1:var b = 1, c = 1, e = 2; var a = b ? (c) : d => e; console.log(a);
outputs
1.nicolo-ribaudo commented
on Jun 7, 2017 ContributorAuthorMore actionsFixing this might introduce an ambiguity in the language:
a ? (b) : c => (d) : e => f
How should that expressions be parsed?
a ? function (b) : c { return (d) } : function (e) { return f } // or a ? (b) : function (c) { return function (d) : e { return f } }
j-oliveras commented
on Jun 7, 2017 ContributorMore actionsMohamed Hegazy (@mhegazy), Daniel Rosenwasser (@DanielRosenwasser)
Looks like the compiler has some ambiguity errors if the true branch of ternary operator is wrapped with parenthesis and the false branch is a lambda expression.Another example:
var b = 0, c = 1, e = 2; var a = b ? (c + e) : d => c+e;
is transpiled as:
var b = 0, c = 1, e = 2; var a = b ? function (c) { if (c === void 0) { c = +e; } return c + e; } : ;
I expect that the transpiled output be the same as input (with es6). Or like this (with es5):
var b = 0, c = 1, e = 2; var a = b ? (c + e) : function(d) { return c+e; };
- addedBugA bug in TypeScriptA bug in TypeScriptSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specification
on Jun 7, 2017 DanielRosenwasser commented
on Jun 7, 2017 MemberMore actionsWe need to disambiguate this in the spec. We'll potentially
- Add non-trivial lookahead
- Create a new production that breaks existing code that uses this.
- Keep things the same
j-oliveras commented
on Jun 7, 2017 ContributorMore actionsDaniel Rosenwasser (@DanielRosenwasser) a problem is that the compiler show errors in javascript files with the sample of my previous response:
var b = 0, c = 1, e = 2; var a = b ? (c + e) : d => c+e;
'=' expected.', at first + symbol.
'types' can only be used in a .ts file.', at symbol d.
':' expected.', at last semi-colon.This code has no errors at node and works as expected.
In this case, removing the parenthesis solve the error.
nicolo-ribaudo commented
on Jul 10, 2017 ContributorAuthorMore actionsI have opened a PR to fix this same issue (but for Flow, not TypeScript) in Babylon (the Babel's parser). It basically tries to parse the middle part of a conditional expression up to three times, which should be enough to find the correct way of parsing.
I don't know how the TypeScript parser works, but maybe it could follow a similar approach.ref: babel/babylon#596
- removedSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specification
on Mar 8, 2019 5 remaining items
The trouble with the current parser seems to be that when it parses out:
x ? y => ({ y }) : z => ({ z })It tries to parse
({ y }) : z => ({ z })as an expression, but tries to parse it as an arrow expression to see if it should be one, which it is, because: zcan be a return type. Probably needs some extra context passed down to tell it to reject on the:if we're in a conditional expression.Reacted by T6- addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Jan 21, 2022 Right, we need a context flag that prevents us from parsing a type annotation on an arrow function immediately nested in one of the branches of a conditional expression. Sort of similar to the flag that prevents us from parsing an
inexpression in afor-inloop.My fix in #47550 doesn't use a context flag, but a boolean that gets passed down via the few call sites where it matters. I'll have to look at how that
for-inflag works, as my impression was that it would be difficult to later unset the flag where it needed to be unset (when parens/nesting happens), but maybe I'm wrong.- removedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Jun 13, 2022 - addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Jun 13, 2022 - locked as resolved and limited conversation to collaborators
on Oct 21, 2025
TypeScript Version: Online repl
Code
https://www.typescriptlang.org/play/index.html#src=var%20a%20%3D%20b%20%3F%20(c)%3A%20d%20%3D%3E%20e%3B
Expected behavior:
It is valid javascript, thus it should be parsed correctly
Actual behavior:
It is parsed as