Types for functions like Array.prototype.reduce or RxJS's "scan" seem impossible
See original GitHub issueBug Report
I searched, and couldn’t find a related issue (but I find it very unlikely one doesn’t exist). It seems like there should be something labeled “Design Limitation” or the like?
The basic problem is if you’re using a standard “reducer” callback pattern with a seed that is different from what your reducer returns the returned type is incorrect.
// The type of result is `number`, but should be `string`.
const result = [1, 2, 3].reduce((acc, value) => {
// ~~~~~~~~~~~~~~~~~
// ^-- Error Here: "No overload matches this call"
if (acc === null) {
return '' + value;
} else {
return acc + ', ' + value;
}
}, null);
console.log(result); // "1, 2, 3"
console.log(typeof result); // "string"
🔎 Search Terms
is:issue is:open array reduce
is:issue is:open reduce callback
is:issue is:open reduce "No overload matches this call"
is:issue is:open reduce label:"Design Limitation"
🕗 Version & Regression Information
Any version of TS, to TMK. Specifically tested in 4.2 and 4.4.4
- This is the behavior in every version I tried, and I reviewed the FAQ for entries as best I could. There’s apparently a LOT of them. I didn’t see anything related.
⏯ Playground Link
💻 Code
// The type of result is `number`, but should be `string`.
const result = [1, 2, 3].reduce((acc, value) => {
// ~~~~~~~~~~~~~~~~~
// ^-- Error Here: "No overload matches this call"
if (acc === null) {
return '' + value;
} else {
return acc + ', ' + value;
}
}, null);
console.log(result); // "1, 2, 3"
console.log(typeof result); // "string"
🙁 Actual behavior
A type error, even though the compiled JavaScript is valid.
🙂 Expected behavior
No type error, result
should be a type string
, not number
.
Related:
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:8 (3 by maintainers)
Top Results From Across the Web
Array.prototype.reduce() - JavaScript - MDN Web Docs
The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value ...
Read more >Array method definition revamp: Use case collection #36554
I'd like to create a clearinghouse issue here to collect ... Types for functions like Array.prototype.reduce or RxJS's "scan" seem ...
Read more >reduce - Learn RxJS
Reduces the values from source observable to a single value that's emitted when the source completes. Just like Array.prototype.reduce() .
Read more >Reduce: how and when / Heiker - Observable
Let's talk about the elephant in the Array prototype, the not so loved reduce method but we're not going to discuss whether if...
Read more >Observable | RxJS API Document - ReactiveX
Creates an Observable from an Array, an array-like object, a Promise, ... static create function, but with different type signature, it was impossible...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Our inference process is so fundamentally different here, but it does feel bad that when we have plain local statements, we’re able to dive into the body of this loop and know it’s either been set to
string
ornull
.I think at some point, I would like to pick @ahejlsberg’s brain to understand how control flow analysis deals with these sorts of circularities (it’s been a while for me, so I’ve largely forgotten). Maybe we could brainstorm on something that would work better with higher order functions like these. One issue with our inference process is that in our first pass going through arguments, we “lock in” inferences from expressions that aren’t “contextually sensitive” (e.g. callbacks). The
null
is the only non-contextually sensitive thing here, so it wins. We could play around with tweaks to this process, butThis is an inference problem, but not a typing problem: https://www.typescriptlang.org/play?#code/PTAEBUAsFNQFwJ4AdYHsBmoBO0DOBXAGzlAEtdQADAO3wFsAjaLSgGlAfxN0lSIBMOsSrjhZS1AOaUAdAFgAUIoDGqaqOx4iJALygA2gEZ2AJnYBmALoyc-fMugAeWoUKgAPqFHipAPgAU-gCGysrsAG5BhPjQAJSgOr6gAN6KIKAZmVnZObkZAH6FRcUlhWlgeZVV2QB6ALR1oACiWFioWKAAEszQAFygAEQAcqigqOHMhKhBgnRBcMowFHCQ5KDKUYQDilmkmMGhCTp6LoTxqQp5OHD4WNSgAOQPoADUoJHR0ADcO5kAvqBoIRcLALldoDc7qAQspXo92M83h8Yj9Lv9FH92KdYqiVGpcKhCNAZFNJP4cARiDjQOkBsZQGZQOZtgpVOpCcTSf5ECgMJpKXBqbTvBJJAMgA