diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 04facba3196e7..22aeb9d668270 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -45798,7 +45798,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { : exprType; const effectiveExpr = expr && getEffectiveCheckNode(expr); // The effective expression for diagnostics purposes. - const errorNode = inReturnStatement && !inConditionalExpression ? node : effectiveExpr; + const errorNode = inConditionalExpression ? effectiveExpr : + inReturnStatement ? node : + isArrowFunction(node.parent) && node.parent.type !== undefined ? node.parent.type : + effectiveExpr; // If the return type is not narrowable, we simply check if the return expression type is assignable to the return type. if (!(unwrappedReturnType.flags & (TypeFlags.IndexedAccess | TypeFlags.Conditional)) || !couldContainTypeVariables(unwrappedReturnType)) { diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.errors.txt b/tests/baselines/reference/arrowFunctionErrorSpan.errors.txt index 0cc9ee2b6a98f..bdc28bbb11e70 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.errors.txt +++ b/tests/baselines/reference/arrowFunctionErrorSpan.errors.txt @@ -19,9 +19,11 @@ arrowFunctionErrorSpan.ts(43,5): error TS2345: Argument of type '() => void' is Type 'void' is not assignable to type 'number'. arrowFunctionErrorSpan.ts(52,3): error TS2345: Argument of type '(_: any) => number' is not assignable to parameter of type '() => number'. Target signature provides too few arguments. Expected 1 or more, but got 0. +arrowFunctionErrorSpan.ts(55,7): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. +arrowFunctionErrorSpan.ts(57,7): error TS2322: Type 'string' is not assignable to type 'number'. -==== arrowFunctionErrorSpan.ts (11 errors) ==== +==== arrowFunctionErrorSpan.ts (13 errors) ==== function f(a: () => number) { } // oneliner @@ -112,4 +114,12 @@ arrowFunctionErrorSpan.ts(52,3): error TS2345: Argument of type '(_: any) => num ~~~~~ !!! error TS2345: Argument of type '(_: any) => number' is not assignable to parameter of type '() => number'. !!! error TS2345: Target signature provides too few arguments. Expected 1 or more, but got 0. + + f((): number => { }); + ~~~~~~ +!!! error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. + + f((): number => ''); + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.js b/tests/baselines/reference/arrowFunctionErrorSpan.js index b9dd81a62ea09..085c04a7d3f9d 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.js +++ b/tests/baselines/reference/arrowFunctionErrorSpan.js @@ -54,6 +54,10 @@ f( // comment 1 // body is not a block f(_ => 1 + 2); + +f((): number => { }); + +f((): number => ''); //// [arrowFunctionErrorSpan.js] @@ -91,3 +95,5 @@ function () { // body is not a block f(function (_) { return 1 + 2; }); +f(function () { }); +f(function () { return ''; }); diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.symbols b/tests/baselines/reference/arrowFunctionErrorSpan.symbols index d1c0ff14d50b5..cc602f755ca67 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.symbols +++ b/tests/baselines/reference/arrowFunctionErrorSpan.symbols @@ -81,3 +81,9 @@ f(_ => 1 + 2); +f((): number => { }); +>f : Symbol(f, Decl(arrowFunctionErrorSpan.ts, 0, 0)) + +f((): number => ''); +>f : Symbol(f, Decl(arrowFunctionErrorSpan.ts, 0, 0)) + diff --git a/tests/baselines/reference/arrowFunctionErrorSpan.types b/tests/baselines/reference/arrowFunctionErrorSpan.types index 9b125e6961a6b..0818380bc914f 100644 --- a/tests/baselines/reference/arrowFunctionErrorSpan.types +++ b/tests/baselines/reference/arrowFunctionErrorSpan.types @@ -145,3 +145,21 @@ f(_ => 1 + >2 : 2 > : ^ +f((): number => { }); +>f((): number => { }) : void +> : ^^^^ +>f : (a: () => number) => void +> : ^ ^^ ^^^^^^^^^ +>(): number => { } : () => number +> : ^^^^^^ + +f((): number => ''); +>f((): number => '') : void +> : ^^^^ +>f : (a: () => number) => void +> : ^ ^^ ^^^^^^^^^ +>(): number => '' : () => number +> : ^^^^^^ +>'' : "" +> : ^^ + diff --git a/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.errors.txt b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.errors.txt new file mode 100644 index 0000000000000..dded0d0d783fe --- /dev/null +++ b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.errors.txt @@ -0,0 +1,41 @@ +arrowFunctionReturnTypeErrorSpan.ts(2,7): error TS2451: Cannot redeclare block-scoped variable 'a'. +arrowFunctionReturnTypeErrorSpan.ts(3,3): error TS2322: Type 'string' is not assignable to type 'number'. +arrowFunctionReturnTypeErrorSpan.ts(6,7): error TS2451: Cannot redeclare block-scoped variable 'a'. +arrowFunctionReturnTypeErrorSpan.ts(7,10): error TS2304: Cannot find name 'missing'. +arrowFunctionReturnTypeErrorSpan.ts(11,15): error TS2322: Type 'string' is not assignable to type 'number'. +arrowFunctionReturnTypeErrorSpan.ts(14,15): error TS2322: Type 'string' is not assignable to type 'number'. +arrowFunctionReturnTypeErrorSpan.ts(16,25): error TS2304: Cannot find name 'missing'. + + +==== arrowFunctionReturnTypeErrorSpan.ts (7 errors) ==== + // block body + const a = (): number => { + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'a'. + return "foo"; + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + }; + + const a = (): number => { + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'a'. + return missing; + ~~~~~~~ +!!! error TS2304: Cannot find name 'missing'. + }; + + // expression body + const b = (): number => "foo"; + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + + type F = T; + const c = (): F => "foo"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + + const d = (): number => missing; + ~~~~~~~ +!!! error TS2304: Cannot find name 'missing'. + \ No newline at end of file diff --git a/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.js b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.js new file mode 100644 index 0000000000000..f5ead91daa775 --- /dev/null +++ b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.js @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts] //// + +//// [arrowFunctionReturnTypeErrorSpan.ts] +// block body +const a = (): number => { + return "foo"; +}; + +const a = (): number => { + return missing; +}; + +// expression body +const b = (): number => "foo"; + +type F = T; +const c = (): F => "foo"; + +const d = (): number => missing; + + +//// [arrowFunctionReturnTypeErrorSpan.js] +// block body +var a = function () { + return "foo"; +}; +var a = function () { + return missing; +}; +// expression body +var b = function () { return "foo"; }; +var c = function () { return "foo"; }; +var d = function () { return missing; }; diff --git a/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.symbols b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.symbols new file mode 100644 index 0000000000000..cede2d742170e --- /dev/null +++ b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts] //// + +=== arrowFunctionReturnTypeErrorSpan.ts === +// block body +const a = (): number => { +>a : Symbol(a, Decl(arrowFunctionReturnTypeErrorSpan.ts, 1, 5)) + + return "foo"; +}; + +const a = (): number => { +>a : Symbol(a, Decl(arrowFunctionReturnTypeErrorSpan.ts, 5, 5)) + + return missing; +}; + +// expression body +const b = (): number => "foo"; +>b : Symbol(b, Decl(arrowFunctionReturnTypeErrorSpan.ts, 10, 5)) + +type F = T; +>F : Symbol(F, Decl(arrowFunctionReturnTypeErrorSpan.ts, 10, 30)) +>T : Symbol(T, Decl(arrowFunctionReturnTypeErrorSpan.ts, 12, 7)) +>T : Symbol(T, Decl(arrowFunctionReturnTypeErrorSpan.ts, 12, 7)) + +const c = (): F => "foo"; +>c : Symbol(c, Decl(arrowFunctionReturnTypeErrorSpan.ts, 13, 5)) +>F : Symbol(F, Decl(arrowFunctionReturnTypeErrorSpan.ts, 10, 30)) + +const d = (): number => missing; +>d : Symbol(d, Decl(arrowFunctionReturnTypeErrorSpan.ts, 15, 5)) + diff --git a/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.types b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.types new file mode 100644 index 0000000000000..a7487c88853ee --- /dev/null +++ b/tests/baselines/reference/arrowFunctionReturnTypeErrorSpan.types @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts] //// + +=== arrowFunctionReturnTypeErrorSpan.ts === +// block body +const a = (): number => { +>a : () => number +> : ^^^^^^ +>(): number => { return "foo";} : () => number +> : ^^^^^^ + + return "foo"; +>"foo" : "foo" +> : ^^^^^ + +}; + +const a = (): number => { +>a : () => number +> : ^^^^^^ +>(): number => { return missing;} : () => number +> : ^^^^^^ + + return missing; +>missing : any +> : ^^^ + +}; + +// expression body +const b = (): number => "foo"; +>b : () => number +> : ^^^^^^ +>(): number => "foo" : () => number +> : ^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +type F = T; +>F : T +> : ^ + +const c = (): F => "foo"; +>c : () => F +> : ^^^^^^ +>(): F => "foo" : () => F +> : ^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +const d = (): number => missing; +>d : () => number +> : ^^^^^^ +>(): number => missing : () => number +> : ^^^^^^ +>missing : any +> : ^^^ + diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index aa2ae24033b16..62af626b0aaf8 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -73,7 +73,7 @@ conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'Z Type 'string | number' is not assignable to type 'ZeroOf'. Type 'string' is not assignable to type 'ZeroOf'. conditionalTypes1.ts(263,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. -conditionalTypes1.ts(288,43): error TS2322: Type 'T95' is not assignable to type 'T94'. +conditionalTypes1.ts(288,33): error TS2322: Type 'T95' is not assignable to type 'T94'. Type 'number | boolean' is not assignable to type 'T94'. Type 'number' is not assignable to type 'T94'. Type 'boolean' is not assignable to type 'true'. @@ -465,7 +465,7 @@ conditionalTypes1.ts(288,43): error TS2322: Type 'T95' is not assignable to t type T95 = T extends string ? boolean : number; const f44 = (value: T94): T95 => value; const f45 = (value: T95): T94 => value; // Error - ~~~~~ + ~~~~~~ !!! error TS2322: Type 'T95' is not assignable to type 'T94'. !!! error TS2322: Type 'number | boolean' is not assignable to type 'T94'. !!! error TS2322: Type 'number' is not assignable to type 'T94'. diff --git a/tests/baselines/reference/mappedTypeConstraints2.errors.txt b/tests/baselines/reference/mappedTypeConstraints2.errors.txt index 0d3b3244c9e66..098bbd3f4b21a 100644 --- a/tests/baselines/reference/mappedTypeConstraints2.errors.txt +++ b/tests/baselines/reference/mappedTypeConstraints2.errors.txt @@ -6,7 +6,7 @@ mappedTypeConstraints2.ts(16,11): error TS2322: Type 'Mapped3[Uppercase]' mappedTypeConstraints2.ts(42,7): error TS2322: Type 'Mapped6[keyof Mapped6]' is not assignable to type '`_${string}`'. Type 'Mapped6[string] | Mapped6[number] | Mapped6[symbol]' is not assignable to type '`_${string}`'. Type 'Mapped6[string]' is not assignable to type '`_${string}`'. -mappedTypeConstraints2.ts(51,57): error TS2322: Type 'Foo[`get${T}`]' is not assignable to type 'T'. +mappedTypeConstraints2.ts(51,52): error TS2322: Type 'Foo[`get${T}`]' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo[`get${T}`]'. mappedTypeConstraints2.ts(82,9): error TS2322: Type 'ObjectWithUnderscoredKeys[`_${K}`]' is not assignable to type 'true'. Type 'ObjectWithUnderscoredKeys[`_${string}`]' is not assignable to type 'true'. @@ -75,7 +75,7 @@ mappedTypeConstraints2.ts(82,9): error TS2322: Type 'ObjectWithUnderscoredKeys(t: T, foo: Foo): T => foo[`get${t}`]; // Type 'Foo[`get${T}`]' is not assignable to type 'T' - ~~~~~~~~~~~~~~ + ~ !!! error TS2322: Type 'Foo[`get${T}`]' is not assignable to type 'T'. !!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo[`get${T}`]'. diff --git a/tests/baselines/reference/typeSatisfaction_errorLocations1.errors.txt b/tests/baselines/reference/typeSatisfaction_errorLocations1.errors.txt index 59268272aa9df..9cc168656d3ec 100644 --- a/tests/baselines/reference/typeSatisfaction_errorLocations1.errors.txt +++ b/tests/baselines/reference/typeSatisfaction_errorLocations1.errors.txt @@ -26,13 +26,13 @@ typeSatisfaction_errorLocations1.ts(36,9): error TS2345: Argument of type 'strin typeSatisfaction_errorLocations1.ts(39,3): error TS2322: Type 'string' is not assignable to type 'number'. typeSatisfaction_errorLocations1.ts(43,3): error TS2322: Type 'string' is not assignable to type 'number'. typeSatisfaction_errorLocations1.ts(43,16): error TS1360: Type 'string' does not satisfy the expected type 'number'. -typeSatisfaction_errorLocations1.ts(46,22): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(46,6): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. typeSatisfaction_errorLocations1.ts(47,24): error TS2322: Type 'number' is not assignable to type 'true'. -typeSatisfaction_errorLocations1.ts(48,21): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(48,6): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'. Types of property 'a' are incompatible. Type 'number' is not assignable to type 'true'. -typeSatisfaction_errorLocations1.ts(50,23): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. -typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(50,6): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. +typeSatisfaction_errorLocations1.ts(51,6): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. ==== typeSatisfaction_errorLocations1.ts (24 errors) ==== @@ -133,7 +133,7 @@ typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missin } ((): { a: true } => ({}) satisfies unknown)(); - ~~ + ~~~~~~~~~~~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. !!! related TS2728 typeSatisfaction_errorLocations1.ts:46:8: 'a' is declared here. ((): { a: true } => ({ a: 1 }) satisfies unknown)(); @@ -141,17 +141,17 @@ typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missin !!! error TS2322: Type 'number' is not assignable to type 'true'. !!! related TS6500 typeSatisfaction_errorLocations1.ts:47:8: The expected type comes from property 'a' which is declared here on type '{ a: true; }' ((): { a: true } => obj1 satisfies unknown)(); - ~~~~ + ~~~~~~~~~~~ !!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'. !!! error TS2322: Types of property 'a' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'true'. ((): { a: true } => (({}) satisfies unknown) satisfies unknown)(); - ~~ + ~~~~~~~~~~~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. !!! related TS2728 typeSatisfaction_errorLocations1.ts:50:8: 'a' is declared here. ((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)(); - ~~ + ~~~~~~~~~~~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'. !!! related TS2728 typeSatisfaction_errorLocations1.ts:51:8: 'a' is declared here. \ No newline at end of file diff --git a/tests/cases/compiler/arrowFunctionErrorSpan.ts b/tests/cases/compiler/arrowFunctionErrorSpan.ts index 4c7fff88a9394..b91ccd5991710 100644 --- a/tests/cases/compiler/arrowFunctionErrorSpan.ts +++ b/tests/cases/compiler/arrowFunctionErrorSpan.ts @@ -51,3 +51,7 @@ f( // comment 1 // body is not a block f(_ => 1 + 2); + +f((): number => { }); + +f((): number => ''); diff --git a/tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts b/tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts new file mode 100644 index 0000000000000..bfc2b5a0af8b5 --- /dev/null +++ b/tests/cases/compiler/arrowFunctionReturnTypeErrorSpan.ts @@ -0,0 +1,16 @@ +// block body +const a = (): number => { + return "foo"; +}; + +const a = (): number => { + return missing; +}; + +// expression body +const b = (): number => "foo"; + +type F = T; +const c = (): F => "foo"; + +const d = (): number => missing;