DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Gajus Kuizinas
Gajus Kuizinas

Posted on

The most important ESLint rule: max-params

Let me ask you: What do you think this code does?

resizeImage(imagePath, 300, 200, true, true, 1)
Enter fullscreen mode Exit fullscreen mode

It resizes image... but what exactly does it do? For the most part, we cannot tell without looking up the function definition.

Let's say you are reviewing a PR and it includes this change:

-resizeImage(imagePath, 300, 200, true, true, 1)
+resizeImage(imagePath, 300, 200, false, true, 1)
Enter fullscreen mode Exit fullscreen mode

Can you confidently say what is the impact of this change? For the most part... no. You need to know what each positional argument does.

Let's say you know that the interface is:

function resizeImage(
  imagePath: string,
  width: number,
  height: number,
  upscale: boolean,
  crop: boolean,
  quality: number,
): Promise<Buffer>
Enter fullscreen mode Exit fullscreen mode

But now a PR introduces a change to the parameter order (e.g. to make it consistent with other functions):

function resizeImage(
  imagePath: string,
  width: number,
  height: number,
+  crop: boolean,
  upscale: boolean,
-  crop: boolean,
  quality: number,
): Promise<Buffer>
Enter fullscreen mode Exit fullscreen mode

How do you review this change? Sure, reviewing the interface diff is easy, but what about the dozens or hundreds of diffs that update function invocation?

-resizeImage(imagePath, 300, 200, true, false, 1)
+resizeImage(imagePath, 300, 200, false, true, 1)
resizeImage(imagePath, 300, 200, false, false, 1)
-resizeImage(imagePath, 300, 200, false, true, 1)
+resizeImage(imagePath, 300, 200, false, false, 1)
-resizeImage(imagePath, 300, 200, true, false, 1)
+resizeImage(imagePath, 300, 200, false, true, 1)
Enter fullscreen mode Exit fullscreen mode

Hopefully the problem is self-explanatory: Positional arguments create a breading ground for hard and even impossible bugs to catch/debug/fix, esp. when code needs to be refactored. Fear not though as there is a better way.

Let's start from the start, but this time use a single-object parameter:

resizeImage({
  imagePath,
  width: 300,
  height: 200,
  upscale: true,
  crop: false,
  quality: 1,
})
Enter fullscreen mode Exit fullscreen mode

Can you tell what is the intention behind this code? Yes, you can get a good sense, even if you are not familiar with the implementation.

Can you easily refactor the interface? Yes, linter will warn you if contract is not satisfied.

We end up with positional arguments because they feel the most natural to start with. However, as functions grow in scope, what started as a simple function with 1-2 arguments becomes an unreadable mess.

This is where max-params comes to the rescue. Simply adding an ESLint rule that restricts having functions with more than X parameters ensures that your code remains legible and easy to refactor as your codebase scales.

Top comments (8)

Collapse
 
lukeshiru profile image
Luke Shiru

Nice article! For me, unaries (functions that only take a single argument) are the way to go. Need more parameters? Use currying, tuples or objects depending on your needs. If you really think about it, functions with more than 1 argument are generally a nightmare because we have concerns such as:

  • Is the order of the arguments correct?
  • What happens if we need to change that order?
  • What happens if we need more arguments?

These problems are all resolved if we only use a single argument every time.

Cheers!

Collapse
 
mrcaidev profile image
Yuwang Cai

3 params makes me uncomfortable, 4 makes me crazy πŸ˜†

Collapse
 
tsotsi1 profile image
TSOTSI1

That's awesome, make me wanna digging the ESlint document!

Collapse
 
jesterxl profile image
Jesse Warden

25 arguments is the current record I've used in production. You can hear that ESLint rule screaming from the moon...

Collapse
 
jankapunkt profile image
Jan KΓΌster

Next Todo for all my older projects and packages: reduce all functions to single parameter

Collapse
 
mike0120 profile image
Mike Lu

Thanks for sharing.

Collapse
 
yongchanghe profile image
Yongchang He

Thank you for sharing!

Collapse
 
adhamniazy profile image
Adham Niazy

Thanks for sharing 🀍

Hey 😍

Want to help the DEV Community feel more like a community?

Head over to the Welcome Thread and greet some new community members!