Open DetachHead opened 2 years ago
That would be an awesome addition :) Have you evaluated which types aren't working out of the box?
ones i've noticed so far are listed in the description of #256 - will update the list as i come across more
there's also IterationMap
which isn't a recursive type, but a hardcoded list of numbers from -100
to 100
, so any type that depends on it won't benefit from the increased recursion limit when rewritten to be tail-recursive
i'm not sure how to go about updating it, i don't want to just add 1000 more entries to it because that seems gross. perhaps there's a better solution?
i'm not sure how to go about updating it, i don't want to just add 1000 more entries to it because that seems gross. perhaps there's a better solution?
That is totally fine. The map itself is not dynamic on purpose and is there to optimize TypeScript to make iteration convenient and efficient. In essence, it's there to teach TypeScript how to count. The Next
and Prev
operators operate through it in the most efficient manner.
That would be a conclusive experiment to know if types like Reverse
just work out of the box with tail call optimization.
@millsp ok i've updated IterationMap
to range from -1000 to 1000, and also added a script to make it easier to modify the range in the future. i'll continue looking for and updating types to be tail-recursive within the next few days
is there a reason for using 0
and 1
instead of boolean
s? seems there's quite a lot of types that use if expressions like this
type Foo<T> = {
0: 'foo'
1: 'bar'
}[Condition<T>]
but i don't think that works for tail recursion optimization. is it purely for readability?
Yes, it's because you can index with 0
and 1
but not true
and false
. The reason for this is that extends
clauses are way more expensive than a deterministic index. That means that the compiler is able to flatten such types faster that with an extends
clause.
ah cool i had no idea. so are you ok with me rewriting some of them to use extends
in order to get the tail recursion optimization to work? in my opinion having a 10x higher stack depth outweighs the performance concerns. however from what i understand the optimization results in it evaluating the type more efficiently anyway, but i'm not sure how that compares to the key method
what are your thoughts?
however from what i understand the optimization results in it evaluating the type more efficiently anyway
I also think so. That means that this will be quite an amount of work. In the entry point of the lib, I provided a regex for finding all the recursive types - that will give us an idea of how much there is to do. I'll be happy to contribute on this PR with you :)
sounds good, i had a look through the codebase and yeah it seems like a lot more work than i initially thought and probably won't have the time to do it all myself so any help is appreciated
🍩 Feature Request
Is your feature request related to a problem?
many types in ts toolbelt use recursive conditional types, meaning that using them often results in stack depth errors.
Describe the solution you'd like
in typescript 4.5, tail-recursive conditional types are now optimized such that the recursion limit can be much higher (1000) instead of 100. see the blog post and https://github.com/microsoft/TypeScript/pull/45711
Describe alternatives you've considered
Teachability, Documentation, Adoption, Migration Strategy