Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more readable Error Message Format Proposal #49011

Open
5 tasks done
Ali-Hussein-dev opened this issue May 7, 2022 · 4 comments
Open
5 tasks done

more readable Error Message Format Proposal #49011

Ali-Hussein-dev opened this issue May 7, 2022 · 4 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@Ali-Hussein-dev
Copy link

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

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.

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"}]`
 */

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:

  • 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.

⭐ Suggestions

💻 Use Cases

What workarounds are you using in the meantime?

vscode extension ts-error-translator to make TS messages more readable.

@Ali-Hussein-dev Ali-Hussein-dev changed the title Intuitive-readable Error Message Proposal for some cases more readable Error Message Format Proposal May 7, 2022
@RyanCavanaugh
Copy link
Member

I'm sort of confused, because this is what happens today already:

Missing property

Property 'banana' is missing in type '{ orange: number; apple: number; }' but required in type 'FruitsCountT'.

Excess misspelled property

Type '{ orange: number; banana: number; apples: number; }' is not assignable to type 'FruitsCountT'.
  Object literal may only specify known properties, but 'apples' does not exist in type 'FruitsCountT'. Did you mean to write 'apple'?

Type mismatch - the error spans are on the incorrect property names

  banana: "8",
  ~~~~~~
Type 'string' is not assignable to type 'number'.

Is your suggestion about the phrasing of the message?

@fatcerberus
Copy link

The suggestion seems to be to consolidate all such errors in a given object literal into a single “type error” diagnostic (with the offending properties listed), regardless of nesting level. At present, IIRC, a single object literal may produce multiple error diagnostics.

@danfma
Copy link

danfma commented May 9, 2022

I'm sort of confused, because this is what happens today already:

Missing property

Property 'banana' is missing in type '{ orange: number; apple: number; }' but required in type 'FruitsCountT'.

Excess misspelled property

Type '{ orange: number; banana: number; apples: number; }' is not assignable to type 'FruitsCountT'.
  Object literal may only specify known properties, but 'apples' does not exist in type 'FruitsCountT'. Did you mean to write 'apple'?

Type mismatch - the error spans are on the incorrect property names

  banana: "8",
  ~~~~~~
Type 'string' is not assignable to type 'number'.

Is your suggestion about the phrasing of the message?

I've seen that before. When you have a complex composition, usually, it is almost impossible to find the error because you will have a lot of introspection that makes really hard to understand the reason for the error, even for people with a good understanding of the language.

@Ali-Hussein-dev
Copy link
Author

Ali-Hussein-dev commented May 12, 2022

@RyanCavanaugh
I miss the clear distinction between expectation and what is given as type. I find the second message format shorter, clearer and it tells me where to go to fix it.

// ONE LEVEL OBJECTS:
// current message: Property 'banana' is missing in type '{ orange: number; apple: number; }' but required in type 'FruitsCountT'.
// error message: `groupOne` object is **missing** the  following properties `banana`

// NESTED OBJECTS:
// current message will tell me that is not what TS expects and it assumes where the offending properties come from. 
// error message: `lever1.lever2.level3` object is missing the following properties `a` `b` ...etc // the message tells me where to go (here is level1 is the root type)

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels May 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants