diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 45ec2a9ad427a..f8069daddb984 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4485,6 +4485,10 @@ "category": "Error", "code": 17017 }, + "Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses.": { + "category": "Error", + "code": 17018 + }, "Circularity detected while resolving configuration: {0}": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 481a601118edb..b24fe4abf840c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3857,13 +3857,47 @@ namespace ts { } } else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); + leftOperand = makeBinaryExpression(leftOperand, parseTokenNode>(), tryParseArrowFunctionExpressionOrExpression() || parseBinaryExpressionOrHigher(newPrecedence)); } } - return leftOperand; } + function tryParseArrowFunctionExpressionOrExpression() { + // Much of the time, users will write code along the lines of + // + // let x = foo || () => { /*...*/ } + // + // However, arrow functions aren't valid in those positions in the ECMAScript grammar. + // Despite that, we'll try to parse it out anyway and give a decent error message. + if (isParenthesizedArrowFunctionExpression() !== Tristate.False) { + const maybeArrowFunction = lookAhead(tryParseParenthesizedArrowFunctionExpression); + if (maybeArrowFunction) { + parseErrorAtNode(maybeArrowFunction, Diagnostics.Arrow_functions_are_not_syntactically_valid_here_Consider_wrapping_the_function_in_parentheses); + return maybeArrowFunction; + } + } + if (lookAhead(isStartOfSimpleArrowFunction)) { + const arrowFunction = tryParseAsyncSimpleArrowFunctionExpression() || parseSimpleArrowFunctionExpression(parseBinaryExpressionOrHigher(/*precedence*/ 0)); + parseErrorAtNode(arrowFunction, Diagnostics.Arrow_functions_are_not_syntactically_valid_here_Consider_wrapping_the_function_in_parentheses); + return arrowFunction; + } + return undefined; + } + + function parseErrorAtNode(node: Node, message: DiagnosticMessage, arg0?: any): void { + const start = skipTrivia(sourceFile.text, node.pos) + parseErrorAtPosition(start, node.end - start, message, arg0) + } + + function isStartOfSimpleArrowFunction() { + if (token() === SyntaxKind.AsyncKeyword) { + nextToken(); + return isIdentifier() && nextToken() === SyntaxKind.EqualsGreaterThanToken || token() === SyntaxKind.EqualsGreaterThanToken; + } + return isIdentifier() && nextToken() === SyntaxKind.EqualsGreaterThanToken; + } + function isBinaryOperator() { if (inDisallowInContext() && token() === SyntaxKind.InKeyword) { return false; diff --git a/tests/baselines/reference/ambiguousGenericAssertion1.errors.txt b/tests/baselines/reference/ambiguousGenericAssertion1.errors.txt index 54b463109b140..b7bc3fc72703a 100644 --- a/tests/baselines/reference/ambiguousGenericAssertion1.errors.txt +++ b/tests/baselines/reference/ambiguousGenericAssertion1.errors.txt @@ -1,23 +1,26 @@ tests/cases/compiler/ambiguousGenericAssertion1.ts(4,10): error TS1109: Expression expected. -tests/cases/compiler/ambiguousGenericAssertion1.ts(4,15): error TS2304: Cannot find name 'x'. -tests/cases/compiler/ambiguousGenericAssertion1.ts(4,16): error TS1005: ')' expected. -tests/cases/compiler/ambiguousGenericAssertion1.ts(4,19): error TS1005: ',' expected. -tests/cases/compiler/ambiguousGenericAssertion1.ts(4,21): error TS1005: ';' expected. +tests/cases/compiler/ambiguousGenericAssertion1.ts(4,10): error TS2365: Operator '>' cannot be applied to types 'number' and '(x: any) => boolean'. +tests/cases/compiler/ambiguousGenericAssertion1.ts(4,12): error TS2304: Cannot find name 'T'. +tests/cases/compiler/ambiguousGenericAssertion1.ts(4,14): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/ambiguousGenericAssertion1.ts(4,18): error TS2304: Cannot find name 'T'. +tests/cases/compiler/ambiguousGenericAssertion1.ts(4,24): error TS2304: Cannot find name 'T'. -==== tests/cases/compiler/ambiguousGenericAssertion1.ts (5 errors) ==== +==== tests/cases/compiler/ambiguousGenericAssertion1.ts (6 errors) ==== function f(x: T): T { return null; } var r = (x: T) => x; var r2 = < (x: T) => T>f; // valid var r3 = <(x: T) => T>f; // ambiguous, appears to the parser as a << operation ~~ !!! error TS1109: Expression expected. - ~ -!!! error TS2304: Cannot find name 'x'. - ~ -!!! error TS1005: ')' expected. - ~ -!!! error TS1005: ',' expected. - ~~ -!!! error TS1005: ';' expected. + ~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'number' and '(x: any) => boolean'. + ~ +!!! error TS2304: Cannot find name 'T'. + ~~~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + ~ +!!! error TS2304: Cannot find name 'T'. + ~ +!!! error TS2304: Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/ambiguousGenericAssertion1.js b/tests/baselines/reference/ambiguousGenericAssertion1.js index 8d40873036caa..2b48b0a97d9cf 100644 --- a/tests/baselines/reference/ambiguousGenericAssertion1.js +++ b/tests/baselines/reference/ambiguousGenericAssertion1.js @@ -9,5 +9,5 @@ var r3 = <(x: T) => T>f; // ambiguous, appears to the parser as a << operatio function f(x) { return null; } var r = function (x) { return x; }; var r2 = f; // valid -var r3 = << T > (x), T; -T > f; // ambiguous, appears to the parser as a << operation +var r3 = << T > (function (x) { return T > f; }); +(function (x) { return T > f; }); // ambiguous, appears to the parser as a << operation diff --git a/tests/baselines/reference/ambiguousGenericAssertion1.symbols b/tests/baselines/reference/ambiguousGenericAssertion1.symbols index dab5bcbc4eb6c..194331595eb83 100644 --- a/tests/baselines/reference/ambiguousGenericAssertion1.symbols +++ b/tests/baselines/reference/ambiguousGenericAssertion1.symbols @@ -23,8 +23,8 @@ var r2 = < (x: T) => T>f; // valid var r3 = <(x: T) => T>f; // ambiguous, appears to the parser as a << operation >r3 : Symbol(r3, Decl(ambiguousGenericAssertion1.ts, 3, 3)) ->T : Symbol(T, Decl(ambiguousGenericAssertion1.ts, 3, 16)) ->T : Symbol(T, Decl(ambiguousGenericAssertion1.ts, 3, 16)) ->T : Symbol(T, Decl(ambiguousGenericAssertion1.ts, 3, 16)) +>x : Symbol(x, Decl(ambiguousGenericAssertion1.ts, 3, 14)) +>f : Symbol(f, Decl(ambiguousGenericAssertion1.ts, 0, 0)) +>x : Symbol(x, Decl(ambiguousGenericAssertion1.ts, 3, 14)) >f : Symbol(f, Decl(ambiguousGenericAssertion1.ts, 0, 0)) diff --git a/tests/baselines/reference/ambiguousGenericAssertion1.types b/tests/baselines/reference/ambiguousGenericAssertion1.types index bb37c64a0cede..3e783df683df5 100644 --- a/tests/baselines/reference/ambiguousGenericAssertion1.types +++ b/tests/baselines/reference/ambiguousGenericAssertion1.types @@ -18,13 +18,17 @@ var r2 = < (x: T) => T>f; // valid var r3 = <(x: T) => T>f; // ambiguous, appears to the parser as a << operation >r3 : boolean -><(x : boolean +>< : boolean >< : any >T : any ->(x : any +>(x: T) => T>f : (x: any) => boolean >x : any +>T>f : boolean >T : any +>f : (x: T) => T +>(x: T) => T>f : (x: any) => boolean +>x : any >T>f : boolean >T : any >f : (x: T) => T diff --git a/tests/baselines/reference/incorrectArrowFunction.errors.txt b/tests/baselines/reference/incorrectArrowFunction.errors.txt new file mode 100644 index 0000000000000..0b46b6590f1c6 --- /dev/null +++ b/tests/baselines/reference/incorrectArrowFunction.errors.txt @@ -0,0 +1,65 @@ +tests/cases/compiler/incorrectArrowFunction.ts(7,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(8,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(9,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(10,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(11,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(12,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(13,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(14,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(15,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. +tests/cases/compiler/incorrectArrowFunction.ts(16,9): error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + + +==== tests/cases/compiler/incorrectArrowFunction.ts (10 errors) ==== + declare const foo; + + interface Foo { + a: number + } + + true || () => 1; + ~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || a => 1; + ~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || a => b => 1; + ~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || (a) => 2; + ~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || foo => 1; + ~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || (a: number) => 1; + ~~~~~~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || ({ a }: Foo) => 1; + ~~~~~~~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || async() => 1; + ~~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || async a => 1; + ~~~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + true || async => 1; + ~~~~~~~~~~ +!!! error TS17018: Arrow functions are not syntactically valid here. Consider wrapping the function in parentheses. + + true || (() => 1); + true || (a => 1); + true || ((a) => 2); + true || (foo => 1); + true || ((a: number) => 1); + true || (({ a }: Foo) => 1); + true || (async () => 1); + true || (async a => 1); + true || (async => 1); + (() => 1) || (() => 2); + + true || (false); + true || false; + true || foo; + \ No newline at end of file diff --git a/tests/baselines/reference/incorrectArrowFunction.js b/tests/baselines/reference/incorrectArrowFunction.js new file mode 100644 index 0000000000000..55d489ca6a8ff --- /dev/null +++ b/tests/baselines/reference/incorrectArrowFunction.js @@ -0,0 +1,118 @@ +//// [incorrectArrowFunction.ts] +declare const foo; + +interface Foo { + a: number +} + +true || () => 1; +true || a => 1; +true || a => b => 1; +true || (a) => 2; +true || foo => 1; +true || (a: number) => 1; +true || ({ a }: Foo) => 1; +true || async() => 1; +true || async a => 1; +true || async => 1; + +true || (() => 1); +true || (a => 1); +true || ((a) => 2); +true || (foo => 1); +true || ((a: number) => 1); +true || (({ a }: Foo) => 1); +true || (async () => 1); +true || (async a => 1); +true || (async => 1); +(() => 1) || (() => 2); + +true || (false); +true || false; +true || foo; + + +//// [incorrectArrowFunction.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var _this = this; +true || function () { return 1; }; +(function () { return 1; }); +true || function (a) { return 1; }; +true || function (a) { return function (b) { return 1; }; }; +true || function (a) { return 2; }; +(function (a) { return 2; }); +true || function (foo) { return 1; }; +true || (function (a) { return 1; }); +(function (a) { return 1; }); +true || (function (_a) { + var a = _a.a; + return 1; +}); +(function (_a) { + var a = _a.a; + return 1; +}); +true || (function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, 1]; +}); }); }); +(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, 1]; +}); }); }); +true || (function (a) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, 1]; +}); }); }); +true || function (async) { return 1; }; +true || (function () { return 1; }); +true || (function (a) { return 1; }); +true || (function (a) { return 2; }); +true || (function (foo) { return 1; }); +true || (function (a) { return 1; }); +true || (function (_a) { + var a = _a.a; + return 1; +}); +true || (function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, 1]; +}); }); }); +true || (function (a) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, 1]; +}); }); }); +true || (function (async) { return 1; }); +(function () { return 1; }) || (function () { return 2; }); +true || (false); +true || false; +true || foo; diff --git a/tests/baselines/reference/incorrectArrowFunction.symbols b/tests/baselines/reference/incorrectArrowFunction.symbols new file mode 100644 index 0000000000000..850ecd9ddee9b --- /dev/null +++ b/tests/baselines/reference/incorrectArrowFunction.symbols @@ -0,0 +1,74 @@ +=== tests/cases/compiler/incorrectArrowFunction.ts === +declare const foo; +>foo : Symbol(foo, Decl(incorrectArrowFunction.ts, 0, 13)) + +interface Foo { +>Foo : Symbol(Foo, Decl(incorrectArrowFunction.ts, 0, 18)) + + a: number +>a : Symbol(Foo.a, Decl(incorrectArrowFunction.ts, 2, 15)) +} + +true || () => 1; +true || a => 1; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 7, 7)) + +true || a => b => 1; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 8, 7)) +>b : Symbol(b, Decl(incorrectArrowFunction.ts, 8, 12)) + +true || (a) => 2; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 9, 9)) +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 9, 9)) + +true || foo => 1; +>foo : Symbol(foo, Decl(incorrectArrowFunction.ts, 10, 7)) + +true || (a: number) => 1; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 11, 9)) +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 11, 9)) + +true || ({ a }: Foo) => 1; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 12, 10)) +>Foo : Symbol(Foo, Decl(incorrectArrowFunction.ts, 0, 18)) +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 12, 10)) +>Foo : Symbol(Foo, Decl(incorrectArrowFunction.ts, 0, 18)) + +true || async() => 1; +true || async a => 1; +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 14, 13)) + +true || async => 1; +>async : Symbol(async, Decl(incorrectArrowFunction.ts, 15, 7)) + +true || (() => 1); +true || (a => 1); +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 18, 9)) + +true || ((a) => 2); +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 19, 10)) + +true || (foo => 1); +>foo : Symbol(foo, Decl(incorrectArrowFunction.ts, 20, 9)) + +true || ((a: number) => 1); +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 21, 10)) + +true || (({ a }: Foo) => 1); +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 22, 11)) +>Foo : Symbol(Foo, Decl(incorrectArrowFunction.ts, 0, 18)) + +true || (async () => 1); +true || (async a => 1); +>a : Symbol(a, Decl(incorrectArrowFunction.ts, 24, 14)) + +true || (async => 1); +>async : Symbol(async, Decl(incorrectArrowFunction.ts, 25, 9)) + +(() => 1) || (() => 2); + +true || (false); +true || false; +true || foo; +>foo : Symbol(foo, Decl(incorrectArrowFunction.ts, 0, 13)) + diff --git a/tests/baselines/reference/incorrectArrowFunction.types b/tests/baselines/reference/incorrectArrowFunction.types new file mode 100644 index 0000000000000..06ad8e5b1dc7a --- /dev/null +++ b/tests/baselines/reference/incorrectArrowFunction.types @@ -0,0 +1,187 @@ +=== tests/cases/compiler/incorrectArrowFunction.ts === +declare const foo; +>foo : any + +interface Foo { + a: number +>a : number +} + +true || () => 1; +>true || : true | (() => number) +>true : true +>() => 1 : () => number +>1 : 1 +>() => 1 : () => number +>1 : 1 + +true || a => 1; +>true || a => 1 : true | ((a: any) => number) +>true : true +>a => 1 : (a: any) => number +>a : any +>1 : 1 + +true || a => b => 1; +>true || a => b => 1 : true | ((a: any) => (b: any) => number) +>true : true +>a => b => 1 : (a: any) => (b: any) => number +>a : any +>b => 1 : (b: any) => number +>b : any +>1 : 1 + +true || (a) => 2; +>true || : true | ((a: any) => number) +>true : true +>(a) => 2 : (a: any) => number +>a : any +>2 : 2 +>(a) => 2 : (a: any) => number +>a : any +>2 : 2 + +true || foo => 1; +>true || foo => 1 : true | ((foo: any) => number) +>true : true +>foo => 1 : (foo: any) => number +>foo : any +>1 : 1 + +true || (a: number) => 1; +>true || : true | ((a: number) => number) +>true : true +>(a: number) => 1 : (a: number) => number +>a : number +>1 : 1 +>(a: number) => 1 : (a: number) => number +>a : number +>1 : 1 + +true || ({ a }: Foo) => 1; +>true || : true | (({ a }: Foo) => number) +>true : true +>({ a }: Foo) => 1 : ({ a }: Foo) => number +>a : number +>1 : 1 +>({ a }: Foo) => 1 : ({ a }: Foo) => number +>a : number +>1 : 1 + +true || async() => 1; +>true || : true | (() => Promise) +>true : true +>async() => 1 : () => Promise +>1 : 1 +>async() => 1 : () => Promise +>1 : 1 + +true || async a => 1; +>true || async a => 1 : true | ((a: any) => Promise) +>true : true +>async a => 1 : (a: any) => Promise +>a : any +>1 : 1 + +true || async => 1; +>true || async => 1 : true | ((async: any) => number) +>true : true +>async => 1 : (async: any) => number +>async : any +>1 : 1 + +true || (() => 1); +>true || (() => 1) : true | (() => number) +>true : true +>(() => 1) : () => number +>() => 1 : () => number +>1 : 1 + +true || (a => 1); +>true || (a => 1) : true | ((a: any) => number) +>true : true +>(a => 1) : (a: any) => number +>a => 1 : (a: any) => number +>a : any +>1 : 1 + +true || ((a) => 2); +>true || ((a) => 2) : true | ((a: any) => number) +>true : true +>((a) => 2) : (a: any) => number +>(a) => 2 : (a: any) => number +>a : any +>2 : 2 + +true || (foo => 1); +>true || (foo => 1) : true | ((foo: any) => number) +>true : true +>(foo => 1) : (foo: any) => number +>foo => 1 : (foo: any) => number +>foo : any +>1 : 1 + +true || ((a: number) => 1); +>true || ((a: number) => 1) : true | ((a: number) => number) +>true : true +>((a: number) => 1) : (a: number) => number +>(a: number) => 1 : (a: number) => number +>a : number +>1 : 1 + +true || (({ a }: Foo) => 1); +>true || (({ a }: Foo) => 1) : true | (({ a }: Foo) => number) +>true : true +>(({ a }: Foo) => 1) : ({ a }: Foo) => number +>({ a }: Foo) => 1 : ({ a }: Foo) => number +>a : number +>1 : 1 + +true || (async () => 1); +>true || (async () => 1) : true | (() => Promise) +>true : true +>(async () => 1) : () => Promise +>async () => 1 : () => Promise +>1 : 1 + +true || (async a => 1); +>true || (async a => 1) : true | ((a: any) => Promise) +>true : true +>(async a => 1) : (a: any) => Promise +>async a => 1 : (a: any) => Promise +>a : any +>1 : 1 + +true || (async => 1); +>true || (async => 1) : true | ((async: any) => number) +>true : true +>(async => 1) : (async: any) => number +>async => 1 : (async: any) => number +>async : any +>1 : 1 + +(() => 1) || (() => 2); +>(() => 1) || (() => 2) : () => number +>(() => 1) : () => number +>() => 1 : () => number +>1 : 1 +>(() => 2) : () => number +>() => 2 : () => number +>2 : 2 + +true || (false); +>true || (false) : boolean +>true : true +>(false) : false +>false : false + +true || false; +>true || false : boolean +>true : true +>false : false + +true || foo; +>true || foo : any +>true : true +>foo : any + diff --git a/tests/cases/compiler/incorrectArrowFunction.ts b/tests/cases/compiler/incorrectArrowFunction.ts new file mode 100644 index 0000000000000..69696e16142ce --- /dev/null +++ b/tests/cases/compiler/incorrectArrowFunction.ts @@ -0,0 +1,31 @@ +declare const foo; + +interface Foo { + a: number +} + +true || () => 1; +true || a => 1; +true || a => b => 1; +true || (a) => 2; +true || foo => 1; +true || (a: number) => 1; +true || ({ a }: Foo) => 1; +true || async() => 1; +true || async a => 1; +true || async => 1; + +true || (() => 1); +true || (a => 1); +true || ((a) => 2); +true || (foo => 1); +true || ((a: number) => 1); +true || (({ a }: Foo) => 1); +true || (async () => 1); +true || (async a => 1); +true || (async => 1); +(() => 1) || (() => 2); + +true || (false); +true || false; +true || foo;