diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9ca4828fec1..a7774937f9d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4539,10 +4539,16 @@ namespace ts { // - "(x,y)" is a comma expression parsed as a signature with two parameters. // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. // - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type. - // - "a ? (b): (function() {})" as well, but inside of a parenthesized type. + // - "a ? (b): (function() {})" as well, but inside of a parenthesized type with an arbitrary amount of nesting. // // So we need just a bit of lookahead to ensure that it can only be a signature. - const hasJSDocFunctionType = type && (isJSDocFunctionType(type) || isParenthesizedTypeNode(type) && isJSDocFunctionType(type.type)); + + let unwrappedType = type; + while (unwrappedType?.kind === SyntaxKind.ParenthesizedType) { + unwrappedType = (unwrappedType as ParenthesizedTypeNode).type; // Skip parens if need be + } + + const hasJSDocFunctionType = unwrappedType && isJSDocFunctionType(unwrappedType); if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== SyntaxKind.OpenBraceToken)) { // Returning undefined here will cause our caller to rewind to where we started from. return undefined; diff --git a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.js b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.js index 2aa4a3989b9..2dd2b52f85f 100644 --- a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.js +++ b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.js @@ -1,8 +1,10 @@ //// [parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts] let a: any; const c = true ? (a) : (function() {}); +const d = true ? (a) : ((function() {})); //// [parserParenthesizedVariableAndParenthesizedFunctionInTernary.js] var a; var c = true ? (a) : (function () { }); +var d = true ? (a) : ((function () { })); diff --git a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.symbols b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.symbols index 9e2db3a1f66..c133ddc1157 100644 --- a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.symbols +++ b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.symbols @@ -6,3 +6,7 @@ const c = true ? (a) : (function() {}); >c : Symbol(c, Decl(parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts, 1, 5)) >a : Symbol(a, Decl(parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts, 0, 3)) +const d = true ? (a) : ((function() {})); +>d : Symbol(d, Decl(parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts, 2, 5)) +>a : Symbol(a, Decl(parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts, 0, 3)) + diff --git a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.types b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.types index 5d9ee98ad92..dd705f6858e 100644 --- a/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.types +++ b/tests/baselines/reference/parserParenthesizedVariableAndParenthesizedFunctionInTernary.types @@ -11,3 +11,13 @@ const c = true ? (a) : (function() {}); >(function() {}) : () => void >function() {} : () => void +const d = true ? (a) : ((function() {})); +>d : any +>true ? (a) : ((function() {})) : any +>true : true +>(a) : any +>a : any +>((function() {})) : () => void +>(function() {}) : () => void +>function() {} : () => void + diff --git a/tests/cases/conformance/parser/ecmascript5/parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts b/tests/cases/conformance/parser/ecmascript5/parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts index 6b22d3dd12c..af061cec05b 100644 --- a/tests/cases/conformance/parser/ecmascript5/parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts +++ b/tests/cases/conformance/parser/ecmascript5/parserParenthesizedVariableAndParenthesizedFunctionInTernary.ts @@ -1,2 +1,3 @@ let a: any; const c = true ? (a) : (function() {}); +const d = true ? (a) : ((function() {}));