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
5.6 regression: Array.prototype.reduce type inference regression #59763
Building TypeScript...
TypeScript built successfully!
git bisect good a71841c is the first bad commit
commit a71841c
Author: Mateusz Burzyński mateuszburzynski@gmail.com
Date: Tue Jun 18 00:25:06 2024 +0200
Eh, for some reason I was looking at the other playground - the one that doesn't reproduce the issue.
I agree with Ryan Cavanaugh (@RyanCavanaugh) that this is more correct (although number enums are at times more permissive/unsound, see bitmasks using them). I don't like how the outcome depends on whether the type is wrapped in a container type or not though. I'll look into this bit
It's a bit harder though to more abstractly decide what is appropriate behavior for code like:
function func(a: T, b: T): T;
When called with a and b that are slightly different types.
Yes, that's true. It's decided today based on heuristics that have been found to produce good results. In a case like this, it tries to find a common supertype among the candidates, and if none is found then the leftmost candidate gets preferred (so whatever was passed in as a). It's a little bit of an oversimplification since getCovariantInference has some more logic. I just want to say that the algorithm for this is not "perfect" - it uses local heuristics and those are subject to change. That doesn't mean that regressions are taken lightly but this is not a set of strict unchangeable rules. Hyrum's law applies here just like anywhere else. IMHO, past behavior can't be the deciding factor in situations like this because it would effectively strangle progress altogether.
changed the title [-]Array.prototype.reduce type inference regression[/-][+]5.6 regression: Array.prototype.reduce type inference regression[/+]on Aug 27, 2024
The difference between those 2 cases is quite surprising here - especially given how this was accidentally affected by the change in inferred type selection. It boils down to how reduce overloads are structured:
Notice that the first one uses different (unrelated) types for its parameters while the second one has parameters of the same type. So what happens here is that the second case never gets to the inference-based overload*, it stops at the second one since this candidate is perfectly applicable**.
*It gets to it in the first subtype-based pass but not in the second assignable-based pass of chooseOverload
**Perfectly applicable under current set of rules according to which number always is assignable to numeric enums
Activity
Andarist commentedon Aug 26, 2024
Thanks for the repro! I'll investigate this one soon. Based on my quick check this one is not related to #57909
RyanCavanaugh commentedon Aug 26, 2024
🤔
Building TypeScript...
TypeScript built successfully!
git bisect good
a71841c is the first bad commit
commit a71841c
Author: Mateusz Burzyński mateuszburzynski@gmail.com
Date: Tue Jun 18 00:25:06 2024 +0200
RyanCavanaugh commentedon Aug 26, 2024
I would say this is a correct result. From the compiler's POV,
Math.minis no different fromMath.pow, and it's inarguable thatwould more correctly be
numberthanSomeEnumtrevorade commentedon Aug 26, 2024
I can see this being an improvement as well in this specific case.
It's a bit harder though to more abstractly decide what is appropriate behavior for code like:
When called with
aandbthat are slightly different types.I would argue that past behavior should be the guiding principle.
I have another regression that is similar to this: #59764
trevorade commentedon Aug 26, 2024
Confirmed that #59709 does not resolve this issue.
Andarist commentedon Aug 27, 2024
Eh, for some reason I was looking at the other playground - the one that doesn't reproduce the issue.
I agree with Ryan Cavanaugh (@RyanCavanaugh) that this is more correct (although number enums are at times more permissive/unsound, see bitmasks using them). I don't like how the outcome depends on whether the type is wrapped in a container type or not though. I'll look into this bit
Yes, that's true. It's decided today based on heuristics that have been found to produce good results. In a case like this, it tries to find a common supertype among the candidates, and if none is found then the leftmost candidate gets preferred (so whatever was passed in as
a). It's a little bit of an oversimplification sincegetCovariantInferencehas some more logic. I just want to say that the algorithm for this is not "perfect" - it uses local heuristics and those are subject to change. That doesn't mean that regressions are taken lightly but this is not a set of strict unchangeable rules. Hyrum's law applies here just like anywhere else. IMHO, past behavior can't be the deciding factor in situations like this because it would effectively strangle progress altogether.[-]Array.prototype.reduce type inference regression[/-][+]5.6 regression: Array.prototype.reduce type inference regression[/+]Andarist commentedon Aug 27, 2024
The difference between those 2 cases is quite surprising here - especially given how this was accidentally affected by the change in inferred type selection. It boils down to how
reduceoverloads are structured:callbackfnis given those 2 types respectively:Notice that the first one uses different (unrelated) types for its parameters while the second one has parameters of the same type. So what happens here is that the second case never gets to the inference-based overload*, it stops at the second one since this candidate is perfectly applicable**.
*It gets to it in the first subtype-based pass but not in the second assignable-based pass of
chooseOverload**Perfectly applicable under current set of rules according to which number always is assignable to numeric enums
typescript-bot commentedon Aug 30, 2024
This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes.