question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Require initialValue for .reduce()

See original GitHub issue

I’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:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

7reactions
mdjermanoviccommented, Feb 3, 2020

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:

/* eslint "no-restricted-syntax": ["error",
  {
    "selector": "CallExpression[arguments.length=1] > MemberExpression.callee > Identifier.property[name='reduce']",
    "message": "Provide initialValue to .reduce()."
  }
]
*/        

arr.reduce(f); // error

values.reduce((a, b) => a + b); // error

values.reduce((a, b) => a + b, 0); // ok

Online Demo

1reaction
kaicataldocommented, Feb 4, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JavaScript reduce behavior with/without an initial value
reduce() , it uses the first element of the array as the accumulator and starts at the second element. In the first example,...
Read more >
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 >
A Guide To The Reduce Method In Javascript​ - freeCodeCamp
The initial value is the value of the total parameter when the reduction starts.
Read more >
Using the JavaScript Array Reduce Method With or Without ...
As a reminder, the reduce method requires a callback function that can take up to four arguments: those that are required, previous value ......
Read more >
JavaScript reduce() Method: Ultimate Guide (with Examples)
JavaScript reduce() Method: Ultimate Guide (with Examples) · Takes an initial value. · Sets the result as the initial value to start with....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found