Repository: TypeScript
Issue: Improve the error message you get when casting a type to one that is not compatible.
Labels: Suggestion,Help Wanted,Experience Enhancement

# Suggestion

## 🔍 Search Terms

"may be a mistake because neither type sufficiently" ts2352 unhelpful helpful message 

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
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, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

A better error message when casting a type where one of its functions has the incorrect return type.

## 📃 Motivating Example

Consider the following code: ([playground](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgLIE8CS5rycgbwChlTkYB7CgLmQGcwpQBzAbhLICM4paGmQbDqQC26AGIgAFAEo+jFuwC+RIggogGyAB7IAvIWHIxk2YbIXkUCGACuUEMka2I7CyqXI4dNFhyxEVyIgA))
```ts
interface MyInterface {
    foo: string;
    bar: string;
    myFn(): string;
}

const x = {
    myFn() {
        return true;
    }
} as MyInterface;
```
In this case TypeScript will complain that the cast object does not sufficiently overlap with `MyInterface`:
```
Conversion of type '{ myFn(): boolean; }' to type 'MyInterface' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '{ myFn(): boolean; }' is missing the following properties from type 'MyInterface': foo, bar(2352)
```

Suggesting that the fix is to add `foo` and `bar` to the type. But in reality the issue is that `myFn()` returns an incorrect type, a `boolean` instead of a `string`.

## 💻 Use Cases

When writing unit tests I use this pattern a lot for mocking dependencies. In the example above, you can add `foo` and `bar` to the object, which will turn the error into:
```
Conversion of type '{ myFn(): boolean; foo: string; bar: string; }' to type 'MyInterface' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  The types returned by 'myFn()' are incompatible between these types.
    Type 'boolean' is not comparable to type 'string'.(2352)
```
which is exactly the kind of message I'm looking for. Now in the example above this is a viable workaround, you add a few extra types in order to find out where you messed up. But consider the following ([playground](https://www.typescriptlang.org/play?#code/MYewdgzgLgBAtiYBrA6gUwEYGVFLbAXhgG8AoGCmAc3wCUQQoA5EAEzQAoBKE8y-gE74ArgLAwwwgDZSA3HwoBfUopgBDCDAASAFQCyAGQCSYAA7CoAUSlo4aMFHlA)):
```ts
const mockWebSocket = {
    getRootNode() {
        return null;
    }
} as HTMLInputElement;
```
Now the error is:
```
Conversion of type '{ getRootNode(): null; }' to type 'HTMLInputElement' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '{ getRootNode(): null; }' is missing the following properties from type 'HTMLInputElement': accept, align, alt, autocomplete, and 332 more.(2352)
```
In this case, implementing all 335 properties just so you can find the actual mistake is not a viable workaround anymore.