Repository: TypeScript
Issue: Improve error messages for return values within annotated arrow functions.
Labels: Suggestion,Experience Enhancement

## Search Terms

Domain: Error Messages arrow function annotation fresh return type

## Suggestion

Currently, when an arrow function is annotated with a function signature type, any errors which occur point to the variable being assigned. Here's an example:

```tsx
type SplitName = (name: string) => {
    first: string;
    last: string;
}

const splitName: SplitName = (name) => {
    // ^ Type '(name: string) => { first: string; }' is not assignable to type 'SplitName'.
    //     Property 'last' is missing in type '{ first: string; }' but required in type '{ first: string; last: string; }'.(2322)
    //   input.tsx(3, 5): 'last' is declared here.
    const [first, lost] = name.split(" ");
    return { first, lost };
}
```

Because this function's arguments match the signature, it should be possible to give a more specific error:

```tsx
const splitName: SplitName = (name) => {
    const [first, lost] = name.split(" ");
    return { first, lost };
    //              ^ Type '{ first: string; lost: string; }' is not assignable to type '{ first: string; last: string; }'.
    //                  Object literal may only specify known properties, and 'lost' does not exist in type '{ first: string; last: string; }'.
}
```

This is very helpful in more complex cases.

This behavior would match the error message shown when manually annotating the return value of the function. Using `ReturnType<>` matches the proposed error message exactly, for all return values I've tried, provided that the type is not a union:

```tsx
const splitName: SplitName = (name): ReturnType<SplitName> => {
    const [first, lost] = name.split(" ");
    return { first, lost };
    //              ^ Type '{ first: string; lost: string; }' is not assignable to type '{ first: string; last: string; }'.
    //                  Object literal may only specify known properties, and 'lost' does not exist in type '{ first: string; last: string; }'.
}
```

It might be best to avoid applying this elaboration to union types of any kind, as the error messages end up being applied to both the variable _and_ the return value, which ends up being worse than the current error:

```tsx
type SplitNameObj = (name: string) => {first: string, last: string};
type SplitNameTuple = (name: string) => [first: string, last: string];
type SplitName = SplitNameObj | SplitNameTuple;

const splitName: SplitName = (name): ReturnType<SplitName> => {
    // ^ Type '(name: string) => { first: string; last: string; } | [first: string, last: string]' is not assignable to type 'SplitName'.
    //     Type '(name: string) => { first: string; last: string; } | [first: string, last: string]' is not assignable to type 'SplitNameObj'.
    //       Type '{ first: string; last: string; } | [first: string, last: string]' is not assignable to type '{ first: string; last: string; }'.
    //         Type '[first: string, last: string]' is not assignable to type '{ first: string; last: string; }'.(2322)

    const [first, lost] = name.split(" ");
    const returnValue = { first, lost };
    return returnValue;
    //     ^ Type '{ first: string; lost: string; }' is not assignable to type '{ first: string; last: string; } | [first: string, last: string]'.
    //         Property 'last' is missing in type '{ first: string; lost: string; }' but required in type '{ first: string; last: string; }'.(2322)
    //       input.tsx(1, 55): 'last' is declared here.
}
```

## Checklist

My suggestion meets these guidelines:

* [X] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [X] This wouldn't change the runtime behavior of existing JavaScript code
* [X] This could be implemented without emitting different JS based on the types of the expressions
* [X] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
* [X] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).