Skip to content

Commit def09f8

Browse files
feat(eslint-plugin): [restrict-plus-operands] add allow* options (#6161)
* feat(eslint-plugin): [restrict-plus-operands] add allow* options from restrict-template-expressions * Warn explicitly * Update packages/eslint-plugin/docs/rules/restrict-plus-operands.md Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * Brad suggestion * Fix lint-markdown --------- Co-authored-by: Brad Zacher <brad.zacher@gmail.com>
1 parent a91bb9e commit def09f8

File tree

4 files changed

+975
-340
lines changed

4 files changed

+975
-340
lines changed

packages/eslint-plugin/docs/rules/restrict-plus-operands.md

+135-25
Original file line numberDiff line numberDiff line change
@@ -18,70 +18,180 @@ This rule reports when a `+` operation combines two values of different types, o
1818
### ❌ Incorrect
1919

2020
```ts
21-
var foo = '5.5' + 5;
22-
var foo = 1n + 1;
21+
let foo = '5.5' + 5;
22+
let foo = 1n + 1;
2323
```
2424

2525
### ✅ Correct
2626

2727
```ts
28-
var foo = parseInt('5.5', 10) + 10;
29-
var foo = 1n + 1n;
28+
let foo = parseInt('5.5', 10) + 10;
29+
let foo = 1n + 1n;
3030
```
3131

3232
## Options
3333

34-
### `checkCompoundAssignments`
34+
:::caution
35+
We generally recommend against using these options, as they limit which varieties of incorrect `+` usage can be checked.
36+
This in turn severely limits the validation that the rule can do to ensure that resulting strings and numbers are correct.
37+
38+
Safer alternatives to using the `allow*` options include:
39+
40+
- Using variadic forms of logging APIs to avoid needing to `+` values.
41+
```ts
42+
// Remove this line
43+
console.log('The result is ' + true);
44+
// Add this line
45+
console.log('The result is', true);
46+
```
47+
- Using `.toFixed()` to coerce numbers to well-formed string representations:
48+
```ts
49+
const number = 1.123456789;
50+
const result = 'The number is ' + number.toFixed(2);
51+
// result === 'The number is 1.12'
52+
```
53+
- Calling `.toString()` on other types to mark explicit and intentional string coercion:
54+
```ts
55+
const arg = '11';
56+
const regex = /[0-9]/;
57+
const result =
58+
'The result of ' +
59+
regex.toString() +
60+
'.test("' +
61+
arg +
62+
'") is ' +
63+
regex.test(arg).toString();
64+
// result === 'The result of /[0-9]/.test("11") is true'
65+
```
66+
67+
:::
3568

36-
Examples of code for this rule with `{ checkCompoundAssignments: true }`:
69+
### `allowAny`
70+
71+
Examples of code for this rule with `{ allowAny: true }`:
3772

3873
<!--tabs-->
3974

4075
#### ❌ Incorrect
4176

4277
```ts
43-
/*eslint @typescript-eslint/restrict-plus-operands: ["error", { "checkCompoundAssignments": true }]*/
78+
let fn = (a: number, b: []) => a + b;
79+
let fn = (a: string, b: []) => a + b;
80+
```
4481

45-
let foo: string | undefined;
46-
foo += 'some data';
82+
#### ✅ Correct
4783

48-
let bar: string = '';
49-
bar += 0;
84+
```ts
85+
let fn = (a: number, b: any) => a + b;
86+
let fn = (a: string, b: any) => a + b;
87+
```
88+
89+
### `allowBoolean`
90+
91+
Examples of code for this rule with `{ allowBoolean: true }`:
92+
93+
<!--tabs-->
94+
95+
#### ❌ Incorrect
96+
97+
```ts
98+
let fn = (a: number, b: unknown) => a + b;
99+
let fn = (a: string, b: unknown) => a + b;
50100
```
51101

52102
#### ✅ Correct
53103

54104
```ts
55-
/*eslint @typescript-eslint/restrict-plus-operands: ["error", { "checkCompoundAssignments": true }]*/
105+
let fn = (a: number, b: boolean) => a + b;
106+
let fn = (a: string, b: boolean) => a + b;
107+
```
56108

57-
let foo: number = 0;
58-
foo += 1;
109+
### `allowNullish`
59110

60-
let bar = '';
61-
bar += 'test';
111+
Examples of code for this rule with `{ allowNullish: true }`:
112+
113+
<!--tabs-->
114+
115+
#### ❌ Incorrect
116+
117+
```ts
118+
let fn = (a: number, b: unknown) => a + b;
119+
let fn = (a: number, b: never) => a + b;
120+
let fn = (a: string, b: unknown) => a + b;
121+
let fn = (a: string, b: never) => a + b;
62122
```
63123

64-
### `allowAny`
124+
#### ✅ Correct
65125

66-
Examples of code for this rule with `{ allowAny: true }`:
126+
```ts
127+
let fn = (a: number, b: undefined) => a + b;
128+
let fn = (a: number, b: null) => a + b;
129+
let fn = (a: string, b: undefined) => a + b;
130+
let fn = (a: string, b: null) => a + b;
131+
```
132+
133+
### `allowNumberAndString`
134+
135+
Examples of code for this rule with `{ allowNumberAndString: true }`:
67136

68137
<!--tabs-->
69138

70139
#### ❌ Incorrect
71140

72141
```ts
73-
var fn = (a: any, b: boolean) => a + b;
74-
var fn = (a: any, b: []) => a + b;
75-
var fn = (a: any, b: {}) => a + b;
142+
let fn = (a: number, b: unknown) => a + b;
143+
let fn = (a: number, b: never) => a + b;
76144
```
77145

78146
#### ✅ Correct
79147

80148
```ts
81-
var fn = (a: any, b: any) => a + b;
82-
var fn = (a: any, b: string) => a + b;
83-
var fn = (a: any, b: bigint) => a + b;
84-
var fn = (a: any, b: number) => a + b;
149+
let fn = (a: number, b: string) => a + b;
150+
let fn = (a: number, b: number | string) => a + b;
151+
```
152+
153+
### `allowRegExp`
154+
155+
Examples of code for this rule with `{ allowRegExp: true }`:
156+
157+
<!--tabs-->
158+
159+
#### ❌ Incorrect
160+
161+
```ts
162+
let fn = (a: number, b: RegExp) => a + b;
163+
```
164+
165+
#### ✅ Correct
166+
167+
```ts
168+
let fn = (a: string, b: RegExp) => a + b;
169+
```
170+
171+
### `checkCompoundAssignments`
172+
173+
Examples of code for this rule with `{ checkCompoundAssignments: true }`:
174+
175+
<!--tabs-->
176+
177+
#### ❌ Incorrect
178+
179+
```ts
180+
let foo: string | undefined;
181+
foo += 'some data';
182+
183+
let bar: string = '';
184+
bar += 0;
185+
```
186+
187+
#### ✅ Correct
188+
189+
```ts
190+
let foo: number = 0;
191+
foo += 1;
192+
193+
let bar = '';
194+
bar += 'test';
85195
```
86196

87197
## When Not To Use It

0 commit comments

Comments
 (0)