Repository: TypeScript
Issue: more readable Error Message Format Proposal
Labels: Suggestion,Awaiting More Feedback

# Suggestion
When TS compares two object types and objects that don't have a compatible type, TS shows often a messy message which makes things worse. When comparing two object types, I found there are three main categories why they are not compatible,
1. missing properties, 
2. unknown properties, 
3. incompatible properties type
based on that, TS can show much more readable error messages by pointing just to the case/s (missing, unknown, and incompatible properties) which cause the error. 

## 📃 Motivating Example
Here is an example of what I think TS should show
```ts
interface FruitsCountT {
  orange: number
  apple: number
  banana: number 
}
// case 1
const groupOne: FruitsCountT= {
  orange:4,
  apple: 8,
}
// error message: `groupOne` is **missing** the  following properties `banana`

// case 2
const groupTwo: FruitsCountT= {
  orange:4, 
  banana: 8,
apples: 10
}
// error message: `groupTwo` has **unknown** properties `apples`, did you mean `apple`

// case 3
const groupThree: FruitsCountT= {
  orange:4,
  banana: "8",
  apple: "10", 
}

/**
 * Error message: the following properties don't have compatible type as expected, 
 * for `apple` I expect a number but you give me a string
 * for `banana` I expect a number but you give me a string
 */
```
When two or more cases happen at the same time, then a separate message for each case, the user should expect. 

For nested objects, I think an object-property should be handled the same as if it is an independent object. 
here is an example of nested objects. 
```ts
interface MenuT {
  id: string;
  drinks: {
    softdrinks: string[];
    juices: string[];
  };
  dishes: {
    pasta: string[];
    salads: string[];
  };
}
const menu: MenuT = {
  id: '1',
  drinks: {
    softdrinks: [],
 // missing 
  },
  dishes: {
    pasta: [{name:"Lasagna"}], // incompatible 
    salad: ["tuna salad"], // unknown
  },
};
/**
 * the object has three type errors: 
 * error message: `menu.dishes` has unknown properties `salad`, did you mean `salads`?
 * error message: `menu.drinks` is missing the following properties `juices` 
 * error message: `pasta` property type, I expect `string[]` but you give `[{name:"Lasagna"}]`
 */
```
<!--
  Please fill in each section completely. Thank you!
-->

List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.

## ✅ Viability 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, 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).


## ⭐ Suggestions


<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
-->
 ### What workarounds are you using in the meantime?
vscode extension [ts-error-translator](https://github.com/mattpocock/ts-error-translator) to make TS messages more readable.