Require initialValue for .reduce()
See original GitHub issueI’m reposting this from a proposal I found at the TSLINT project, at https://github.com/palantir/tslint/issues/4173. I have found problems in a code base myself, which would have been avoided if this rule had been in place, so I second the proposal.
Please describe what the rule should do:
Requires initialValue
to be specified when calling Array.prototype.reduce()
When using Array.prototype.reduce()
the initialValue
parameter is optional. As per MDN docs: “If the array is empty and no initialValue
is provided, TypeError will be thrown.” Therefore the suggestion is to provide a rule where the initialValue is required to be specified to avoid TypeErrors being raised.
What category of rule is this? (place an “X” next to just one item)
[X] Warns about a potential error (problem) [ ] Suggests an alternate way of doing something (suggestion) [ ] Enforces code style (layout) [ ] Other (please specify:)
It is a general problem that is likely to occur as the code grows.
Provide 2-3 code examples that this rule will warn about:
As per MDN docs: “It is usually safer to provide an initial value because there are three possible outputs without initialValue, as shown in the following example.”
var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x );
var maxCallback2 = ( max, cur ) => Math.max( max, cur );
// reduce() without initialValue
[ { x: 22 }, { x: 42 } ].reduce( maxCallback ); // 42
[ { x: 22 } ].reduce( maxCallback ); // { x: 22 }
[ ].reduce( maxCallback ); // TypeError
// map/reduce; better solution, also works for empty or larger arrays
[ { x: 22 }, { x: 42 } ].map( el => el.x )
.reduce( maxCallback2, -Infinity );
Another example: when reduce is being called on an array passed in as a parameter, or injected (e.g., using Redux), providing the initialValue
parameter to reduce avoids having to check if the array is empty, however, that is easy to forget while coding.
function sumArray(values: number[]) {
return values.reduce((a, b) => a + b);
}
sumArray([1,2]); // 3
sumArray([]); // TypeError
function sumArrayWithInitial(values: number[]) {
return values.reduce((a, b) => a + b, 0);
}
sumArrayWithInitial([]); // 0
Why should this rule be included in ESLint (instead of a plugin)?
This is a generic JavaScript rule, not linked to frameworks or libraries.
Are you willing to submit a pull request to implement this rule?
Don’t have enough knowledge about writing rules, so “no” at least at this time.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:8 (7 by maintainers)
Top GitHub Comments
Hi @fkereki, thanks for the new rule proposal!
I think this would be a useful rule, but its scope might be too narrow for a core rule since it’s targeting only one specific method.
If the rule doesn’t reach consensus to be included in the core, an alternative may be to configure the generic no-restricted-syntax rule to catch this:
Online Demo
I agree that this would be a useful rule, but I echo @mdjermanovic’s thoughts above. We have a very small volunteer-based team and have a lot of rules to maintain. We have to set a very high bar for new rules in core and, as this can be covered by
no-restricted-syntax
, I’m not sure this proposal meets that bar. Let’s see what others on the team have to say.