Every branch in a function is one more path to keep in mind and to test. This rule counts them and reports any function with more than 20.
The count starts at 1. Each of these adds 1: if, ? :, a loop, a case, a catch, &&, ||, ??, their assignment forms such as ||=, ?., and a default value for a parameter or in destructuring. Nested functions are counted separately. Class field initializers and static blocks are counted too.
Configure
Off by default. To turn it on:
[lint.rules]
"complexity" = "error" # or "warn"
Every option, set to its default. The ones that are commented out are unset by default.
[lint.rules]
"complexity" = ["error", {
max = 20,
variant = "classic", # "classic" or "modified"
# maximum = <number>,
}]
Examples
With a maximum of 3, this function is reported. It has a complexity of 4:
function shipping(order) {
if (order.total > 100) {
return 0;
} else if (order.express) {
return 15;
} else if (order.country !== "US") {
return 25;
}
return 5;
}
Not reported:
function shipping(order) {
if (order.total > 100) {
return 0;
}
return order.express ? 15 : standardRate(order.country);
}
function standardRate(country) {
return country === "US" ? 5 : 25;
}
Options
[lint.rules]
complexity = ["error", 10]
The option is either a number (the maximum) or an object:
| Option | Default | What it does |
|---|---|---|
max | 20 | The highest complexity allowed. maximum is an older name for it. |
variant | "classic" | "modified" counts a whole switch as 1, no matter how many cases it has. |
Three cases give this function a complexity of 4. default doesn't count:
function label(status) {
switch (status) {
case "open":
return "Open";
case "merged":
return "Merged";
case "closed":
return "Closed";
default:
return "Unknown";
}
}
With "modified", the same function has a complexity of 2:
function label(status) {
switch (status) {
case "open":
return "Open";
case "merged":
return "Merged";
case "closed":
return "Closed";
default:
return "Unknown";
}
}