| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) test this |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized community code test suite on this PR at 7c4d923. You can monitor the build here. |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 7c4d923. You can monitor the build here. |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at 7c4d923. You can monitor the build here. |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the perf test suite on this PR at 7c4d923. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) Comparison Report - master..40002
System
Hosts
Scenarios
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
| } | ||
|
|
||
| function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) { | ||
| function invokeWithDepthLimit(source: Type, target: Type, action: (source: Type, target: Type) => void) { |
There was a problem hiding this comment.
This is pretty much the inference equivalent of recursiveTypeRelatedTo at this point.
Sorry, something went wrong.
| } | ||
| if (type.flags & TypeFlags.Conditional) { | ||
| // The root object represents the origin of the conditional type | ||
| return (type as ConditionalType).root; |
There was a problem hiding this comment.
Huh, and this doesn't affect the user baselines or DT?
Sorry, something went wrong.
There was a problem hiding this comment.
No. Previously conditional types couldn't be recursive, so they weren't included here. But for that same reason we have no tests that could be affected by this.
Sorry, something went wrong.
|
Awesome to finally see this! 😀 |
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) maybe something worthwhile is to build another PR on top of this to see if changing the definition of FlatArray would impact real-world code. |
Sorry, something went wrong.
|
The tests revealed OOMs in a few projects due to the switch to use isDeeplyNestedType for recursion tracking in type inference (which permits up to five levels of recursion). With the latest commits I have reverted to the previous scheme of terminating after just one level of recursion, but with the added twist that we track both the source and target sides (similarly to recursiveTypeRelatedTo) and terminate only when both have a circularity. Intuitively, in inference we want to terminate when we encounter a duplicate attempt to infer from source and target types with the same origin, so getRecursionIdentity needs to get us as close as possible to the AST node that caused the type instantiation. Because most type instantiations are interned and shared (and thus have no reference to their originating AST node), this isn't always possible. For example, when inferring from Box2<Box2<string>> to Box1<Box1<T>>, where Box1 and Box2 are unique but structurally identical types, we end up with the same recursion identity for each Box1 and Box2 reference, and therefore terminate inference prematurely. This is a known problem (i.e. not new to this PR) and something we should continue to think about. A brute force way to work around the problem is to allow multiple levels of recursion, but that only works up to some level of nested and, as illustrated by the test failures, generates way too much work in general. |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) test this |
Sorry, something went wrong.
|
Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized community code test suite on this PR at fed0e8c. You can monitor the build here. |
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) According to your example in the OP, this also fixes #26223 😊 |
Sorry, something went wrong.
|
Test runs all look clean. Slight regression in check time for material-ui, but it's worth it for the added precision in type inference. |
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) Ron Buckton (@rbuckton) Does this change mean we no longer need hacks like awaited keyword to handle the recursive nature of Promise? |
Sorry, something went wrong.
|
Can we get a playground for this PR? I'd like to play around with the new options this gives us. |
Sorry, something went wrong.
why the max number is 43 ? not 48 ? not 98 ? |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
With this PR we officially support recursive conditional types. For example:
A bit of context... When conditional types were first introduced, we explicitly restricted them to be non-recursive, i.e. we made it an error for a conditional type to directly or indirectly reference itself. This restriction was put in place primarily as a safeguard against runaway infinite recursion which the compiler didn't handle well at the time. However, it turns out it was still possible to construct recursive conditionally resolved types by combining object types (which have deferred resolution of property types) and conditional types using indexed access types (see #14833 for the core idea). In spite of being cumbersome and non-intuitive, this trick has become commonplace in several libraries. Consequently, over time we have "hardened" the compiler against infinite recursion with depth limiters in relationships, type inference, type instantiation, constraint computation, and so on. We're now at a point where it seems reasonable support an intuitive way of writing recursive conditional types.
Some more examples:
Note that this PR doesn't change the recursion depth limits that are already in place. For example, an error is reported on T4 above because its resolution exceeds the limit of 50 nested type instantiations.
The type inference streamlining contained in the PR fixes several issues with inference to recursive types. For example:
Previously, only the unbox(b1) call produced the expected type inference.
Fixes #26223.
Fixes #26980.
Fixes #37801.