Skip to content
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

Array.prototype.reduce return type incorrectly inferred as 'any' when Array has type any[] #34602

Closed
vp2177 opened this issue Oct 20, 2019 · 2 comments

Comments

@vp2177
Copy link

vp2177 commented Oct 20, 2019

TypeScript Version: 3.6.3

Search Terms: Array reduce type inferred bad|incorrect|any

Code

const s: Array<any> = []
const x = s.reduce((a, c) => a + '*', '')

Expected behavior: x should be inferred to be of type string

Actual behavior: x is inferred to be any

However, x is is correctly inferred to be type string, if using [].reduce(... as opposed to s.reduce(....

Compare:
Screenshot 2019-10-20 at 04 54 38
with
Screenshot 2019-10-20 at 04 54 03

Inferring x's type even if s is polymorphic is possible and works in other languages:
Screenshot 2019-10-20 at 04 52 38

Playground Link:

Related Issues:
#21061

@vp2177 vp2177 changed the title Array.prototype.reduce return type incorrectly inferred as 'any' Array.prototype.reduce return type incorrectly inferred as 'any' when Array has type any[] Oct 20, 2019
@jcalz
Copy link
Contributor

jcalz commented Oct 20, 2019

The overloads of reduce() are in a suboptimal order when the array element type is very wide like any or unknown (if the initial value is assignable to it). If the generic call signature were moved to the front, this issue would not arise:

interface Array<T> {
  reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U
  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;
}

const s: Array<unknown> = []
const x = s.reduce((a, c) => a + '*', ''); // string

Playground link

I'm not sure if this rises to the level of "bug"; in any case, you could always locally merge in the above declarations in your code base to resolve it (actually you only need the generic one).

@vp2177
Copy link
Author

vp2177 commented Oct 20, 2019

Thank you!
Then I think this is a duplicate of #7014.

@vp2177 vp2177 closed this as completed Oct 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants