]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | # Require parens in arrow function arguments (arrow-parens) |
2 | ||
3 | Arrow functions can omit parentheses when they have exactly one parameter. In all other cases the parameter(s) must | |
4 | be wrapped in parentheses. This rule enforces the consistent use of parentheses in arrow functions. | |
5 | ||
6 | ## Rule Details | |
7 | ||
8 | This rule enforces parentheses around arrow function parameters regardless of arity. For example: | |
9 | ||
10 | ```js | |
11 | /*eslint-env es6*/ | |
12 | ||
13 | // Bad | |
14 | a => {} | |
15 | ||
16 | // Good | |
17 | (a) => {} | |
18 | ``` | |
19 | ||
20 | Following this style will help you find arrow functions (`=>`) which may be mistakenly included in a condition | |
21 | when a comparison such as `>=` was the intent. | |
22 | ||
eb39fafa DC |
23 | ```js |
24 | /*eslint-env es6*/ | |
25 | ||
26 | // Bad | |
27 | if (a => 2) { | |
28 | } | |
29 | ||
30 | // Good | |
31 | if (a >= 2) { | |
32 | } | |
33 | ``` | |
34 | ||
35 | The rule can also be configured to discourage the use of parens when they are not required: | |
36 | ||
37 | ```js | |
38 | /*eslint-env es6*/ | |
39 | ||
40 | // Bad | |
41 | (a) => {} | |
42 | ||
43 | // Good | |
44 | a => {} | |
45 | ``` | |
46 | ||
47 | ## Options | |
48 | ||
49 | This rule has a string option and an object one. | |
50 | ||
51 | String options are: | |
52 | ||
53 | * `"always"` (default) requires parens around arguments in all cases. | |
5422a9cc | 54 | * `"as-needed"` enforces no parens where they can be omitted. |
eb39fafa DC |
55 | |
56 | Object properties for variants of the `"as-needed"` option: | |
57 | ||
58 | * `"requireForBlockBody": true` modifies the as-needed rule in order to require parens if the function body is in an instructions block (surrounded by braces). | |
59 | ||
60 | ### always | |
61 | ||
62 | Examples of **incorrect** code for this rule with the default `"always"` option: | |
63 | ||
64 | ```js | |
65 | /*eslint arrow-parens: ["error", "always"]*/ | |
66 | /*eslint-env es6*/ | |
67 | ||
68 | a => {}; | |
69 | a => a; | |
70 | a => {'\n'}; | |
71 | a.then(foo => {}); | |
72 | a.then(foo => a); | |
73 | a(foo => { if (true) {} }); | |
74 | ``` | |
75 | ||
76 | Examples of **correct** code for this rule with the default `"always"` option: | |
77 | ||
78 | ```js | |
79 | /*eslint arrow-parens: ["error", "always"]*/ | |
80 | /*eslint-env es6*/ | |
81 | ||
82 | () => {}; | |
83 | (a) => {}; | |
84 | (a) => a; | |
85 | (a) => {'\n'} | |
86 | a.then((foo) => {}); | |
87 | a.then((foo) => { if (true) {} }); | |
88 | ``` | |
89 | ||
90 | #### If Statements | |
91 | ||
92 | One of the benefits of this option is that it prevents the incorrect use of arrow functions in conditionals: | |
93 | ||
94 | ```js | |
95 | /*eslint-env es6*/ | |
96 | ||
97 | var a = 1; | |
98 | var b = 2; | |
99 | // ... | |
100 | if (a => b) { | |
101 | console.log('bigger'); | |
102 | } else { | |
103 | console.log('smaller'); | |
104 | } | |
105 | // outputs 'bigger', not smaller as expected | |
106 | ``` | |
107 | ||
108 | The contents of the `if` statement is an arrow function, not a comparison. | |
109 | ||
110 | If the arrow function is intentional, it should be wrapped in parens to remove ambiguity. | |
111 | ||
112 | ```js | |
113 | /*eslint-env es6*/ | |
114 | ||
115 | var a = 1; | |
116 | var b = 0; | |
117 | // ... | |
118 | if ((a) => b) { | |
119 | console.log('truthy value returned'); | |
120 | } else { | |
121 | console.log('falsey value returned'); | |
122 | } | |
123 | // outputs 'truthy value returned' | |
124 | ``` | |
125 | ||
126 | The following is another example of this behavior: | |
127 | ||
128 | ```js | |
129 | /*eslint-env es6*/ | |
130 | ||
131 | var a = 1, b = 2, c = 3, d = 4; | |
132 | var f = a => b ? c: d; | |
133 | // f = ? | |
134 | ``` | |
135 | ||
136 | `f` is an arrow function which takes `a` as an argument and returns the result of `b ? c: d`. | |
137 | ||
138 | This should be rewritten like so: | |
139 | ||
140 | ```js | |
141 | /*eslint-env es6*/ | |
142 | ||
143 | var a = 1, b = 2, c = 3, d = 4; | |
144 | var f = (a) => b ? c: d; | |
145 | ``` | |
146 | ||
147 | ### as-needed | |
148 | ||
149 | Examples of **incorrect** code for this rule with the `"as-needed"` option: | |
150 | ||
151 | ```js | |
152 | /*eslint arrow-parens: ["error", "as-needed"]*/ | |
153 | /*eslint-env es6*/ | |
154 | ||
155 | (a) => {}; | |
156 | (a) => a; | |
157 | (a) => {'\n'}; | |
158 | a.then((foo) => {}); | |
159 | a.then((foo) => a); | |
160 | a((foo) => { if (true) {} }); | |
ebb53d86 TL |
161 | const f = /** @type {number} */(a) => a + a; |
162 | const g = /* comment */ (a) => a + a; | |
163 | const h = (a) /* comment */ => a + a; | |
eb39fafa DC |
164 | ``` |
165 | ||
166 | Examples of **correct** code for this rule with the `"as-needed"` option: | |
167 | ||
168 | ```js | |
169 | /*eslint arrow-parens: ["error", "as-needed"]*/ | |
170 | /*eslint-env es6*/ | |
171 | ||
172 | () => {}; | |
173 | a => {}; | |
174 | a => a; | |
175 | a => {'\n'}; | |
176 | a.then(foo => {}); | |
177 | a.then(foo => { if (true) {} }); | |
178 | (a, b, c) => a; | |
179 | (a = 10) => a; | |
180 | ([a, b]) => a; | |
181 | ({a, b}) => a; | |
ebb53d86 TL |
182 | const f = (/** @type {number} */a) => a + a; |
183 | const g = (/* comment */ a) => a + a; | |
184 | const h = (a /* comment */) => a + a; | |
eb39fafa DC |
185 | ``` |
186 | ||
187 | ### requireForBlockBody | |
188 | ||
189 | Examples of **incorrect** code for the `{ "requireForBlockBody": true }` option: | |
190 | ||
191 | ```js | |
192 | /*eslint arrow-parens: [2, "as-needed", { "requireForBlockBody": true }]*/ | |
193 | /*eslint-env es6*/ | |
194 | ||
195 | (a) => a; | |
196 | a => {}; | |
197 | a => {'\n'}; | |
198 | a.map((x) => x * x); | |
199 | a.map(x => { | |
200 | return x * x; | |
201 | }); | |
202 | a.then(foo => {}); | |
203 | ``` | |
204 | ||
205 | Examples of **correct** code for the `{ "requireForBlockBody": true }` option: | |
206 | ||
207 | ```js | |
208 | /*eslint arrow-parens: [2, "as-needed", { "requireForBlockBody": true }]*/ | |
209 | /*eslint-env es6*/ | |
210 | ||
211 | (a) => {}; | |
212 | (a) => {'\n'}; | |
213 | a => ({}); | |
214 | () => {}; | |
215 | a => a; | |
216 | a.then((foo) => {}); | |
217 | a.then((foo) => { if (true) {} }); | |
218 | a((foo) => { if (true) {} }); | |
219 | (a, b, c) => a; | |
220 | (a = 10) => a; | |
221 | ([a, b]) => a; | |
222 | ({a, b}) => a; | |
223 | ``` | |
224 | ||
225 | ## Further Reading | |
226 | ||
227 | * The `"as-needed", { "requireForBlockBody": true }` rule is directly inspired by the Airbnb | |
228 | [JS Style Guide](https://github.com/airbnb/javascript#arrows--one-arg-parens). |