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