TypeScript: Version 3.4-dev breaks recursive types
TypeScript Version: 3.4.0-dev.20190302
Search Terms: recursive types
I recently published an article about how to create types for curry and ramda. Quite a few people are excited and waiting for me to add these types to DefinitelyTyped. But I can’t pass the lint
tests yet.
To create these (curry) types, I detail how I make use of recursive types. But TS 3.4.0-dev.20190302 is indeed breaking these types. In the latest stable version (3.3.3333) warnings arise (only) when we recurse more than 45 times. A recursive type then returns any
if the limit is exceeded (which is nice).
But in TS 3.4.0-dev.20190302 it appears that “Type instantiation is excessively deep and possibly infinite”, which is a breaking behaviour. But in fact it is only possibly infinite, and this is why the previous behaviour should be preferred. any
could just be returned anytime that limit has been exceeded, thus stopping the recursion condition.
However, recursive types seem to break only when they are nested. Any idea why @ahejlsberg ? By breaking this feature, we cannot expect complex types for curry and other tools from ramda.
Code Article: https://medium.freecodecamp.org/typescript-curry-ramda-types-f747e99744ab Repo : https://github.com/pirix-gh/medium/blob/master/types-curry-ramda/src/index.ts
Expected behavior: Updates should not have breaking behaviors
Actual behavior: Breaking behavior on recursive types
Playground Link:
Related Issues: https://github.com/Microsoft/TypeScript/issues/29511
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 67
- Comments: 26 (13 by maintainers)
Commits related to this issue
- fix(type): Reduce the number of type parameters Due to Microsoft/TypeScript/issues/30188 — committed to phenyl/sp2 by shinout 5 years ago
- Remove another case so that max depth is 6 keys because of https://github.com/Microsoft/TypeScript/issues/30188 — committed to garbles/useful-types by garbles 5 years ago
- https://github.com/Microsoft/TypeScript/issues/30188 — committed to garbles/useful-types by garbles 5 years ago
- Downgrade TypeScript due to https://github.com/Microsoft/TypeScript/issues/30188 — committed to mmiszy/typesafe-hapi by mmiszy 5 years ago
- Suppress Type instantiation is excessively deep and possibly infinite. IDK whether this is good idea since it disturbs code and deceased readability but it fixes annoying error. refs: - https://kgtk... — committed to ENvironmentSet/welltyped by ENvironmentSet 4 years ago
I you run this on TS 3.4, you should see an error:
Type instantiation is excessively deep and possibly infinite. ts(2589)
It happens when TS decides that types become too complex to compute (ie). The solution is to compute the types that cause problems step by step:
Can this error be disabled? I was unable to find it in the 3.4 breaking changes https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#breaking-changes
Update
This issue causes a lot of errors in the code base that we have at work. It is a large mono repo and we have a lot of recursive types. From example, we have types that map objects into immutable objects and we also have types to work with some data structures such as trees and graphs which are also recursive.
This is a breaking change, my project won’t compile 😐 Should this be reverted in 3.x and rereleased as 4.0?
It’s entirely possible that I’m misunderstanding the above, but I can say with at least some confidence that, with TypeScript 3.3.3, many of my recursive types resolved to types that were very informative/helpful (not just to
any
), whereas, with TypeScript 3.4+, those exact same types now fail to resolve at all, and the “excessively deep and possibly infinite” error is reported. So, there appears to be more going on here than just error reporting.Because of the above, I’d also appreciate this being regarded as a breaking change.
Maybe add posibility to customize “depth” of cheking by config option?
@pirix-gh When we hit the instantiation depth limiter we force the type to terminate by resolving to an
any
. The only change in 3.4 is that we now report an error to let you know that we are delivering truncated (and unpredictable) results. Previously we’d just silently let it pass. So, I’m quite certain you were triggering the limiter before, it’s just that you weren’t hearing about it.@regevbr ts-toolbelt can solve your problem
I just rewrote
getProp
types based on what you’ve said.You can write much shorter types with ts-toolbelt, it computes for you.
I got the same error
The question mark expression about 73 lines, and it writen by tools. vscode give me the error: Type instantiation is excessively deep and possibly infinite.ts(2589)
Thanks @ahejlsberg for your quick reply. Understood.
But from another point of view. Since this is the only way (for now) to build (analysis) types for curry, and a lot of Ramda users are expecting them, can I still publish to DefinitelyTyped even if it does not pass the
lint
tests (exceptionally)?How could we work this out @sandersn ?
I should add that there are two places where we may report that error. One is an instantiation depth of 50 (indicating a possibly infinite type), the other is a constraint depth of 50 (indicating a possibly infinite constraint).
Hi! Thanks! You saved my day! 🙏
Closing issue, as this is clearly a #wontfix. If you need to create complex types, please use ts-toolbelt.
@regevbr thanks & sorry, I did not think about that one. Here’s something more suited:
Thanks, you gave birth to a brand new utility type!
And, remember to update to the latest release 😃
@pirix-gh that looks like a really cool library. But your solution doesn’t provide all I need.
For example the following returns type never, wheres my code will not even allow you to write it as it won’t compile.
Also I also have getPropOr which returns a default value (or computes a default value from a given function for lazy evaluation of the default value). Is it possible to achieve it with toolbelt?
That would be impressive. 😄But (if this was a reply to my latest comment) my hope was just that it would be regarded as a breaking change however it is that you regard things as breaking changes – e.g., by documenting it here.