-
Notifications
You must be signed in to change notification settings - Fork 12.8k
5.6 regression: Array.prototype.reduce type inference regression #59763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for the repro! I'll investigate this one soon. Based on my quick check this one is not related to #57909 |
π€ Building TypeScript... |
I would say this is a correct result. From the compiler's POV, const smallestEnu = vals.reduce(
(minEnu, val) => Math.pow(minEnu, val.enu),
SomeEnum.D,
); would more correctly be |
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: function func<T>(a: T, b: T): T; When called with I would argue that past behavior should be the guiding principle. I have another regression that is similar to this: #59764 |
Confirmed that #59709 does not resolve this issue. |
Eh, for some reason I was looking at the other playground - the one that doesn't reproduce the issue. I agree with @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 |
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(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
(minEnu: SomeEnum, val: SomeType) => number
(minEnu: SomeEnum, enu: SomeEnum) => number 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 |
This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
Inference, Reduce
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?ts=5.6.1-rc#code/JYOwLgpgTgZghgYwgAgMoHsC2EAqBPABxQG8AoZC5CEAVwC40sIBRWzAblIF9TTqbMjbKwHIylZAEFkAXmQBGADTlKAIVnIATMokBhDQGYdlACIaALMp6kAJhAQAbOFBQJ0IAM5hkANzgOPBgxsfCIAbQBdTlI3T28PTH8HCC8RDT8AgDoXGxokAAoVCnzMUBFFX38ASlkAPmQAWTgwAAtM0pASstoKjMz+KuMKYJY2TJNlKs4EpJSwEU4AekXkAD0AfiA
π» Code
π Actual behavior
smallestEnu
has typenumber
π Expected behavior
smallestEnu
has typeSomeEnum
as it did in previous releasesAdditional information about the issue
Interestingly, this does not repro if you remove the container type:
https://www.typescriptlang.org/play/?ts=5.6.1-rc#code/KYOwrgtgBAyg9hYBRc0DeAoK2oEEoC8UAjADRY4BChUATOTlAMI0DMDOAIjQCzkC+GDABNgAYwA2AQwBOwKGLggAzgBcooSMoBcsBMlQBtALoBuIYpXrlEKRInA1KMDU0RlAOjnCwY4AAoKbH8IAEsQZ1INcABKQgA+KABZKVUACw8wkBDwyOiwGI5seERnCA9OchjzGzsHJ3BzAHomqAA9AH4MIA
(Google note: relevant source location http://shortn/_JgMRGaMa4e)
The text was updated successfully, but these errors were encountered: