You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Typescript: Realistic type definition errors #35247
It's not always true that the fully expanded type is more readable than the type alias.
I personally manually control the emit of my types (via type hackery) to try and get the best error message I can. (Rather than relying on TS' default emit algorithm)
Maybe something like this?
"badProp" does not exist on type `Partial<IEventTableNeeds> & IEventCreateNeeds`.
"badProp" does not exist on type with keys requestId, type, id, createdAt, data
Maybe also do a Levenshtein distance on valid strings and suggest the closest match?
I personally manually control the emit of my types (via type hackery)
How do I get started on that?
And I'm sure this is one of those threads that once you start pulling it never stops... but, never-the-less, it couldn't be any worse than it is for some of these errors.
A way to reproduce the error you saw would be very useful. We can sometimes improve error messages based on the use case.
Anyway it's not at all clear what the right rule is here; if one way were just always better than the other, that's the one we'd be doing by now (one would hope).
I suppose the ideal would be some form of switching between the two. I don't expect that to have any easy way, but (if it was possible) it might be like:
Get error: Partial<Omit<Options, "orientation">>
click "show flattened"
have it turn to the long bare version
then click "show symbolic" to go back.
Anyway it's not at all clear what the right rule is here;
Perhaps there is a way to pass this logic off to user land? There are some things I'd like to try.
Speculatively, I think it might be effective to show flat versions of anything with a symbolic tree of over 3-4 nodes. Other times, it could perhaps fit both the symbolic and flat version one after another.
I've been getting really into advanced, conditional, and utility types for my projects.
Wesley Wigham (@weswigham) That would definitely be a good way to go about it. Really, anything works for me, as long as I can see what the final list of properties and types for them is.
Your last two examples just look like type emit problems.
The thing is, I feel like most people don't know how to get the current type system/emitter to produce "good" type emit. Especially for complex generic types.
There are tricks for these things. But sometimes, the types are just too large and some amount of difficult-to-read output is unavoidable.
So, errors can become unreadable, despite the team's best efforts, if users create types with unreadable emit in the first place.
I've found a solution for my scenario, and it is to create facade types that are simple and assert their equivalency to my more complex (and realistic) types elsewhere.
I'm not sure what the limitation of facade types is, but so far it's doing the trick.
Just started to find a way to fold a type in error message. I'm new in typescript and sometimes I fight with it so hard to be safe typed. But when I see message like this I start to consider renaming this file back to .js.
Reacted by Seph Reed, Eyþór Freyr Óskarsson, Azat, Carl Johnson and Klemen Oslaj
Activity
AnyhowStep commentedon Nov 20, 2019
Kind of a difficult one.
It's not always true that the fully expanded type is more readable than the type alias.
I personally manually control the emit of my types (via type hackery) to try and get the best error message I can. (Rather than relying on TS' default emit algorithm)
Maybe something like this?
Maybe also do a Levenshtein distance on valid strings and suggest the closest match?
SephReed commentedon Nov 20, 2019
How do I get started on that?
And I'm sure this is one of those threads that once you start pulling it never stops... but, never-the-less, it couldn't be any worse than it is for some of these errors.
AnyhowStep commentedon Nov 21, 2019
To force TS to expand types,
#34556
To force TS to not expand types (situational, doesn't work for all cases),
#34777 (comment)
If you go down this rabbit hole, you may be cursed!
The
Identity<>trick is a measure that forces the type to be expanded (almost?) always.There are other tricks to force a type to be expanded if you can't rewrite a type to use the
Identity<>trick.Try looking at
ts-toolbelt. I forget the name of the type.One such trick is,
However, if
Tis a union type, this will break.Hence, my feature request here, #32909
A workaround is,
This merge trick can force the expansion of the top level object
SephReed commentedon Nov 21, 2019
This is the most helpful response I think I've ever gotten to a GH issue. Thank you very much.... I'm going down the rabbit hole.
RyanCavanaugh commentedon Nov 21, 2019
A way to reproduce the error you saw would be very useful. We can sometimes improve error messages based on the use case.
Anyway it's not at all clear what the right rule is here; if one way were just always better than the other, that's the one we'd be doing by now (one would hope).
Let's say you had something like
and you use
Optionsa lot throughout your code.Somewhere, a function says
and you call it incorrectly.
What would you want to see?
Partial<Omit<Options, "orientation">>which says "Options, but it's all optional, and noorientation" orwhere you will have to manually diff the property list to figure out which one got removed? That would be clearly worse in a lot of cases.
You can't just rely on "Well if the alias appears in the code, then use that" rule either because these types can appear in higher-order forms, e.g.
where you'd still want the unexpanded alias form.
SephReed commentedon Nov 21, 2019
I suppose the ideal would be some form of switching between the two. I don't expect that to have any easy way, but (if it was possible) it might be like:
Partial<Omit<Options, "orientation">>Perhaps there is a way to pass this logic off to user land? There are some things I'd like to try.
Speculatively, I think it might be effective to show flat versions of anything with a symbolic tree of over 3-4 nodes. Other times, it could perhaps fit both the symbolic and flat version one after another.
I've been getting really into advanced, conditional, and utility types for my projects.
weswigham commentedon Nov 21, 2019
A feature for this, mayhaps?
SephReed commentedon Nov 21, 2019
Wesley Wigham (@weswigham) That would definitely be a good way to go about it. Really, anything works for me, as long as I can see what the final list of properties and types for them is.
SephReed commentedon Jan 3, 2020
I'm going to post examples here as they come up.
SephReed commentedon Feb 8, 2020
AnyhowStep commentedon Feb 9, 2020
Your last two examples just look like type emit problems.
The thing is, I feel like most people don't know how to get the current type system/emitter to produce "good" type emit. Especially for complex generic types.
There are tricks for these things. But sometimes, the types are just too large and some amount of difficult-to-read output is unavoidable.
So, errors can become unreadable, despite the team's best efforts, if users create types with unreadable emit in the first place.
SephReed commentedon Feb 10, 2020
I've found a solution for my scenario, and it is to create facade types that are simple and assert their equivalency to my more complex (and realistic) types elsewhere.
I'm not sure what the limitation of facade types is, but so far it's doing the trick.
vadimshvetsov commentedon May 1, 2020
Just started to find a way to fold a type in error message. I'm new in typescript and sometimes I fight with it so hard to be safe typed. But when I see message like this I start to consider renaming this file back to
.js.