New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add prefer-ternary
rule
#514
Changes from 6 commits
0e75c80
efc968a
3fffe86
80a3a15
3b4d6ab
b210f43
eb7aace
d3a4527
52f5344
d59f2b4
bd9e21c
f0bdc34
48a26aa
73a2263
c600475
8beb75e
f75101e
64e9a0b
503493c
5860a73
a325e56
3dfcd8e
25abee5
a99e7ae
6a3c793
ee7f888
b8dd909
59b9b97
51515d8
6688591
8c3a70f
133c2fa
9a7fc8e
428b3c0
59a7970
da5dfd5
e588687
aca1f1e
efff08c
003acc3
8768b41
76c2378
89906b2
853acf9
397c749
f39f38f
23974b3
5b99354
7cb5ee2
1d06eeb
dd81f37
cee4f4d
b37b4a9
7cc55ed
332ae21
cab9830
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
# Prefer ternary expressions over simple `if-else` statements | ||
|
||
This rule enforces the use of ternary expressions over 'simple' `if-else` statements where 'simple' means the consequent and alternate are each one line and have the same basic type and form. | ||
|
||
Using an `if-else` statement typically results in more lines of code than a single lined ternary expression, which leads to an unnecessarily larger codebase that is more difficult to maintain. | ||
|
||
Additionally, using an `if-else` statement can result in defining variables using `let` or `var` solely to be reassigned within the blocks. This leads to varaibles being unnecessarily mutable and prevents `prefer-const` from flagging the variable. | ||
|
||
This rule is fixable. | ||
|
||
|
||
## Fail | ||
|
||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
foo = 4 | ||
} | ||
``` | ||
|
||
```js | ||
if(bar){ | ||
return 3 | ||
} | ||
else{ | ||
return 4 | ||
} | ||
``` | ||
|
||
```js | ||
if(bar){ | ||
throw Error(123) | ||
} | ||
else{ | ||
throw Error(456) | ||
} | ||
``` | ||
|
||
## Pass | ||
|
||
```js | ||
let foo = bar ? 3 : 4 | ||
``` | ||
|
||
```js | ||
return bar ? 3 : 4 | ||
``` | ||
|
||
|
||
```js | ||
let foo = '' | ||
if(bar){ | ||
baz() | ||
foo = 3 | ||
} | ||
else{ | ||
foo = 4 | ||
} | ||
``` | ||
|
||
```js | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
return 4 | ||
} | ||
``` | ||
|
||
```js | ||
throw bar ? Error(123) : Error(456) | ||
``` | ||
|
||
## Options | ||
|
||
This rule can take the following options: | ||
* An object with the following keys: 'assignment', 'return', 'call', 'throw', 'new', 'yield', 'await' | ||
* The string 'always' | ||
|
||
### assignment | ||
The assignment option determines whether the rule will flag assignment expressions. It can take the following values: 'never', 'same', 'always'. Default value is 'same'. | ||
|
||
**never**: the rule will not flag any assignment statements. | ||
With `{assigment: 'never'}` the following would both NOT be flagged: | ||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
foo = 4 | ||
} | ||
``` | ||
|
||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
baz = 4 | ||
} | ||
``` | ||
|
||
**same**: the rule will flag assignment statements assigning to the same variable. | ||
With `{assigment: 'same'}` the following would be flagged: | ||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
foo = 4 | ||
} | ||
``` | ||
With `{assigment: 'same'}` the following would NOT be flagged: | ||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
baz = 4 | ||
} | ||
``` | ||
|
||
|
||
**always**: the rule will flag all assignment statements. | ||
With `{assigment: 'always'}` the following would both be flagged: | ||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
foo = 4 | ||
} | ||
``` | ||
|
||
```js | ||
let foo ='' | ||
if(bar){ | ||
foo = 3 | ||
} | ||
else{ | ||
baz = 4 | ||
} | ||
``` | ||
|
||
### return | ||
The return option determines whether the rule will flag return expressions. It can take a boolean. Default value is true. | ||
With `{return: false}` the following would NOT be flagged: | ||
```js | ||
let foo ='' | ||
if(bar){ | ||
return 3 | ||
} | ||
else{ | ||
return 4 | ||
} | ||
``` | ||
|
||
### call | ||
The call option determines whether the rule will flag call expressions. It can take a boolean. Default value is false. | ||
With `{call: true}` the following would be flagged: | ||
```js | ||
if(bar){ | ||
foo() | ||
} | ||
else{ | ||
baz() | ||
} | ||
``` | ||
|
||
### throw | ||
The throw option determines whether the rule will flag throw statements. It can take a boolean. Default value is true. | ||
With `{thow: false}` the following would NOT be flagged: | ||
```js | ||
if(bar){ | ||
throw Error(123) | ||
} | ||
else{ | ||
throw Error(456) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be a ternary even with an option. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better example should be if (bar) {
throw new Error('foo');
} else{
throw new Error('bar');
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I'm not fully understanding. Are the two of you disagreeing that this should be a use case or are you agreeing that it is just a bad example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm saying that |
||
``` | ||
|
||
### new | ||
The new option determines whether the rule will flag new constructors. It can take a boolean. Default value is false. | ||
With `{new: true}` the following would be flagged: | ||
```js | ||
if(bar){ | ||
new foo() | ||
} | ||
else{ | ||
new baz() | ||
} | ||
``` | ||
|
||
### yield | ||
The yield option determines whether the rule will flag yield expressions. It can take a boolean. Default value is false. | ||
With `{yield: true}` the following would be flagged: | ||
```js | ||
function* foo(index) { | ||
while (index < 10) { | ||
if(index < 3){ | ||
yield index++; | ||
} | ||
else{ | ||
yield index * 2 | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### await | ||
The await option determines whether the rule will flag await expressions. It can take a boolean. Default value is false. | ||
With `{await: true}` the following would be flagged: | ||
```js | ||
async () => { | ||
if(a){ | ||
await foo(); | ||
} | ||
else{ | ||
await bar(); | ||
} | ||
} | ||
``` | ||
|
||
|
||
### 'always' | ||
|
||
Always prefer ternary to simple `if-else` statements. This option is equivalent to ```{assignment: 'always', return: true, call:true, throw: true, new: true, yield: true, await: true}```. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as https://github.com/sindresorhus/eslint-plugin-unicorn/pull/514/files#r380260375. It's a bad practice to put void function calls in a ternary. Only function calls that return a value should be in a ternary.