diff --git a/docs/rules/no-extra-parens.md b/docs/rules/no-extra-parens.md
index 0a358388295a..0eb07bf5dac3 100644
--- a/docs/rules/no-extra-parens.md
+++ b/docs/rules/no-extra-parens.md
@@ -22,6 +22,7 @@ This rule has an object option for exceptions to the `"all"` option:
* `"returnAssign": false` allows extra parentheses around assignments in `return` statements
* `"nestedBinaryExpressions": false` allows extra parentheses in nested binary expressions
* `"ignoreJSX": "none|all|multi-line|single-line"` allows extra parentheses around no/all/multi-line/single-line JSX components. Defaults to `none`.
+* `"enforceForArrowConditionals": false` allows extra parentheses around arrow conditionals expression
### all
@@ -165,6 +166,17 @@ const Component = (
)
const Component = ()
```
+### enforceForArrowConditionals
+
+Examples of **correct** code for this rule with the `"all"` and `{ "enforceForArrowConditionals": true }` options:
+
+```js
+/* eslint no-extra-parens: ["error", "all", { "enforceForArrowConditionals": true }] */
+
+const b = a => 1 ? 2 : 3;
+const d = c => (1 ? 2 : 3);
+```
+
### functions
Examples of **incorrect** code for this rule with the `"functions"` option:
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 0a6a0d0f1dd0..408ad6eacecb 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -44,7 +44,8 @@ module.exports = {
conditionalAssign: { type: "boolean" },
nestedBinaryExpressions: { type: "boolean" },
returnAssign: { type: "boolean" },
- ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] }
+ ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
+ enforceForArrowConditionals: { type: "boolean" }
},
additionalProperties: false
}
@@ -67,6 +68,9 @@ module.exports = {
const NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false;
const EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false;
const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX;
+ const ENFORCE_FOR_ARROW_CONDITIONALS = ALL_NODES && context.options[1] &&
+ context.options[1].enforceForArrowConditionals === true;
+
const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" });
const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" });
@@ -431,6 +435,10 @@ module.exports = {
return;
}
+ if (node.body.type === "ConditionalExpression" && ENFORCE_FOR_ARROW_CONDITIONALS) {
+ return;
+ }
+
if (node.body.type !== "BlockStatement") {
const firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken);
const tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken);
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index b30c42d86d21..01b125741323 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -369,6 +369,10 @@ ruleTester.run("no-extra-parens", rule, {
"/>)"
].join("\n"), options: ["all", { ignoreJSX: "multi-line" }] },
+ // ["all", { enforceForArrowConditionals: true }]
+ { code: "var a = b => 1 ? 2 : 3", options: ["all", { enforceForArrowConditionals: true }], parserOptions: { ecmaVersion: 6 } },
+ { code: "var a = (b) => (1 ? 2 : 3)", options: ["all", { enforceForArrowConditionals: true }], parserOptions: { ecmaVersion: 6 } },
+
{
code: "let a = [ ...b ]",
parserOptions: { ecmaVersion: 2015 }
@@ -922,6 +926,19 @@ ruleTester.run("no-extra-parens", rule, {
options: ["all", { ignoreJSX: "none" }]
}),
+ // ["all", { enforceForArrowConditionals: false }]
+ {
+ code: "var a = (b) => (1 ? 2 : 3)",
+ parserOptions: { ecmaVersion: 6 },
+ options: ["all", { enforceForArrowConditionals: false }],
+ errors: [
+ {
+ message: "Gratuitous parentheses around expression."
+ }
+ ],
+ output: "var a = (b) => 1 ? 2 : 3"
+ },
+
// https://github.com/eslint/eslint/issues/8175
invalid(
"let a = [...(b)]",