fix(lib): reorder Array#reduce/reduceRight overloads in lib.d.ts#63064
fix(lib): reorder Array#reduce/reduceRight overloads in lib.d.ts#63064taronsung wants to merge 4 commits intomicrosoft:mainfrom
Conversation
Reorder the overload declarations for reduce and reduceRight in both ReadonlyArray<T> and Array<T> interfaces so the generic <U> overload (with initialValue: U) is checked before the same-type overload (with initialValue: T). This fixes incorrect type inference when calling reduce/reduceRight with an initial value of a different type than the array elements. Fixes microsoft#7014
|
@microsoft-github-policy-service agree |
The overload order change affects the displayed type signature and improves type inference in some cases (e.g., anyInferenceAnonymousFunctions now correctly infers any[] instead of any when reduce is called with [] as the initial value).
c9dc0ef to
3efe7e1
Compare
3efe7e1 to
4601242
Compare
|
@typescript-bot test it |
|
Hey @RyanCavanaugh, this PR is in an unmergable state, so is missing a merge commit to run against; please resolve conflicts and try again. |
ArshVermaGit
left a comment
There was a problem hiding this comment.
This PR makes a small but highly impactful fix by reordering the overloads for reduce and reduceRight so that the generic <U> overload with initialValue: U is evaluated before the same-type overload. Because TypeScript resolves overloads top-down, the previous order caused incorrect inference when the accumulator type differed from the array element type, leading to confusing errors like the one reported in #7014. Swapping the declarations aligns the type system with real-world usage patterns, allowing the compiler to correctly infer accumulator types without requiring workarounds or explicit annotations. The change is minimal, consistent across both Array<T> and ReadonlyArray<T>, and preserves backward compatibility while improving correctness and developer ergonomics. Overall, this feels like a well-scoped improvement that resolves a long-standing papercut with a clear and maintainable approach.
Summary
Reorder the overload declarations for
reduceandreduceRightin bothReadonlyArray<T>andArray<T>interfaces so the generic<U>overload (withinitialValue: U) is checked before the same-type overload (withinitialValue: T).Problem
When calling
reducewith an initial value of a different type than the array elements, TypeScript incorrectly infers the return type. This is because TypeScript checks overloads in declaration order, and theinitialValue: Toverload matches before the generic<U>overload gets a chance.Example from #7014:
Solution
Swap the order of the two overloads that take an
initialValueparameter:reduce(cb, initialValue: T)thenreduce<U>(cb, initialValue: U)reduce<U>(cb, initialValue: U)thenreduce(cb, initialValue: T)The same change is applied to both
reduceandreduceRightin bothReadonlyArray<T>andArray<T>.Fixes #7014