Microsoft/TypeScript

Improve the error message you get when casting a type to one that is not compatible.

Open

#48.233 aperta il 12 mar 2022

Vedi su GitHub
 (0 commenti) (5 reazioni) (0 assegnatari)TypeScript (6726 fork)batch import
Experience EnhancementHelp WantedSuggestion

Metriche repository

Star
 (48.455 star)
Metriche merge PR
 (Merge medio 6g 17h) (9 PR mergiate in 30 g)

Descrizione

Suggestion

🔍 Search Terms

"may be a mistake because neither type sufficiently" ts2352 unhelpful helpful message

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's 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)

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):

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.

Guida contributor