@codelaw/rules-js 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/NOTICE +19 -0
- package/README.md +90 -2
- package/codelaw-pack.toml +6 -0
- package/data/globals/browser.json +1209 -0
- package/data/globals/commonjs.json +6 -0
- package/data/globals/jest.json +15 -0
- package/data/globals/mocha.json +22 -0
- package/data/globals/node.json +83 -0
- package/data/globals/serviceworker.json +328 -0
- package/data/globals/shared-node-browser.json +73 -0
- package/data/globals/vitest.json +19 -0
- package/data/globals/worker.json +349 -0
- package/data/node/deprecated-api.json +83 -0
- package/data/react/dom-property-aliases.json +131 -0
- package/package.json +14 -4
- package/presets/js/conventions.toml +10 -0
- package/presets/js/recommended.toml +67 -0
- package/presets/node/recommended.toml +13 -0
- package/presets/react/recommended.toml +22 -0
- package/presets/stencil/recommended.toml +18 -0
- package/presets/ts/recommended.toml +27 -0
- package/rules/graph/no-unused-exports.md +135 -0
- package/rules/js/constructor-super.md +77 -0
- package/rules/js/exports-at-end.md +134 -0
- package/rules/js/for-direction.md +106 -0
- package/rules/js/getter-return.md +74 -0
- package/rules/js/import-groups.md +117 -0
- package/rules/js/no-async-promise-executor.md +95 -0
- package/rules/js/no-case-declarations.md +134 -0
- package/rules/js/no-class-assign.md +61 -0
- package/rules/js/no-compare-neg-zero.md +105 -0
- package/rules/js/no-cond-assign.md +135 -0
- package/rules/js/no-const-assign.md +61 -0
- package/rules/js/no-constant-binary-expression.md +83 -0
- package/rules/js/no-constant-condition.md +150 -0
- package/rules/js/no-control-regex.md +84 -0
- package/rules/js/no-debugger.md +99 -0
- package/rules/js/no-default-export.md +88 -0
- package/rules/js/no-delete-var.md +93 -0
- package/rules/js/no-dupe-args.md +61 -0
- package/rules/js/no-dupe-class-members.md +82 -0
- package/rules/js/no-dupe-else-if.md +113 -0
- package/rules/js/no-dupe-keys.md +66 -0
- package/rules/js/no-duplicate-case.md +137 -0
- package/rules/js/no-empty-character-class.md +98 -0
- package/rules/js/no-empty-pattern.md +86 -0
- package/rules/js/no-empty-static-block.md +99 -0
- package/rules/js/no-empty.md +116 -0
- package/rules/js/no-ex-assign.md +121 -0
- package/rules/js/no-extra-boolean-cast.md +107 -0
- package/rules/js/no-fallthrough.md +178 -0
- package/rules/js/no-func-assign.md +62 -0
- package/rules/js/no-global-assign.md +85 -0
- package/rules/js/no-import-assign.md +60 -0
- package/rules/js/no-invalid-regexp.md +86 -0
- package/rules/js/no-irregular-whitespace.md +87 -0
- package/rules/js/no-loss-of-precision.md +82 -0
- package/rules/js/no-misleading-character-class.md +83 -0
- package/rules/js/no-new-native-nonconstructor.md +55 -0
- package/rules/js/no-nonoctal-decimal-escape.md +84 -0
- package/rules/js/no-obj-calls.md +61 -0
- package/rules/js/no-octal.md +84 -0
- package/rules/js/no-prototype-builtins.md +99 -0
- package/rules/js/no-redeclare.md +61 -0
- package/rules/js/no-regex-spaces.md +75 -0
- package/rules/js/no-self-assign.md +91 -0
- package/rules/js/no-setter-return.md +69 -0
- package/rules/js/no-shadow-restricted-names.md +102 -0
- package/rules/js/no-sparse-arrays.md +82 -0
- package/rules/js/no-this-before-super.md +74 -0
- package/rules/js/no-unassigned-vars.md +102 -0
- package/rules/js/no-undef.md +76 -0
- package/rules/js/no-unexpected-multiline.md +91 -0
- package/rules/js/no-unreachable.md +59 -0
- package/rules/js/no-unsafe-finally.md +145 -0
- package/rules/js/no-unsafe-negation.md +71 -0
- package/rules/js/no-unsafe-optional-chaining.md +83 -0
- package/rules/js/no-unused-labels.md +102 -0
- package/rules/js/no-unused-private-class-members.md +126 -0
- package/rules/js/no-unused-vars.md +69 -0
- package/rules/js/no-useless-assignment.md +115 -0
- package/rules/js/no-useless-backreference.md +83 -0
- package/rules/js/no-useless-catch.md +105 -0
- package/rules/js/no-useless-escape.md +81 -0
- package/rules/js/no-var.md +76 -0
- package/rules/js/no-with.md +60 -0
- package/rules/js/prefer-const.md +83 -0
- package/rules/js/prefer-rest-params.md +103 -0
- package/rules/js/prefer-spread.md +95 -0
- package/rules/js/preserve-caught-error.md +122 -0
- package/rules/js/require-yield.md +107 -0
- package/rules/js/use-isnan.md +105 -0
- package/rules/js/valid-typeof.md +111 -0
- package/rules/node/hashbang.md +71 -0
- package/rules/node/no-deprecated-api.md +91 -0
- package/rules/node/no-exports-assign.md +92 -0
- package/rules/node/no-extraneous-import.md +118 -0
- package/rules/node/no-extraneous-require.md +117 -0
- package/rules/node/no-missing-import.md +118 -0
- package/rules/node/no-missing-require.md +117 -0
- package/rules/node/no-process-exit.md +99 -0
- package/rules/node/no-unpublished-import.md +134 -0
- package/rules/node/no-unpublished-require.md +133 -0
- package/rules/react/display-name.md +91 -0
- package/rules/react/exhaustive-deps.md +116 -0
- package/rules/react/hook-prefix.md +108 -0
- package/rules/react/jsx-key.md +99 -0
- package/rules/react/jsx-no-comment-textnodes.md +87 -0
- package/rules/react/jsx-no-duplicate-props.md +66 -0
- package/rules/react/jsx-no-target-blank.md +78 -0
- package/rules/react/jsx-no-undef.md +78 -0
- package/rules/react/no-children-prop.md +80 -0
- package/rules/react/no-danger-with-children.md +83 -0
- package/rules/react/no-deprecated.md +84 -0
- package/rules/react/no-direct-mutation-state.md +102 -0
- package/rules/react/no-find-dom-node.md +72 -0
- package/rules/react/no-is-mounted.md +109 -0
- package/rules/react/no-render-return-value.md +75 -0
- package/rules/react/no-string-refs.md +72 -0
- package/rules/react/no-unescaped-entities.md +69 -0
- package/rules/react/no-unknown-property.md +69 -0
- package/rules/react/props-type-name.md +43 -0
- package/rules/react/require-render-return.md +91 -0
- package/rules/react/rules-of-hooks.md +128 -0
- package/rules/stencil/ban-default-true.md +70 -0
- package/rules/stencil/ban-exported-const-enums.md +60 -0
- package/rules/stencil/ban-prefix.md +76 -0
- package/rules/stencil/decorators-context.md +61 -0
- package/rules/stencil/host-data-deprecated.md +73 -0
- package/rules/stencil/methods-must-be-public.md +69 -0
- package/rules/stencil/no-unused-watch.md +68 -0
- package/rules/stencil/own-methods-must-be-private.md +68 -0
- package/rules/stencil/own-props-must-be-private.md +60 -0
- package/rules/stencil/prefer-vdom-listener.md +67 -0
- package/rules/stencil/prop-readonly.md +63 -0
- package/rules/stencil/props-must-be-public.md +68 -0
- package/rules/stencil/required-jsdoc.md +66 -0
- package/rules/stencil/reserved-member-names.md +70 -0
- package/rules/stencil/strict-mutable.md +75 -0
- package/rules/stencil/tag-prefix.md +75 -0
- package/rules/ts/ban-ts-comment.md +64 -0
- package/rules/ts/no-array-constructor.md +58 -0
- package/rules/ts/no-duplicate-enum-values.md +65 -0
- package/rules/ts/no-empty-object-type.md +65 -0
- package/rules/ts/no-explicit-any.md +61 -0
- package/rules/ts/no-extra-non-null-assertion.md +50 -0
- package/rules/ts/no-misused-new.md +70 -0
- package/rules/ts/no-namespace.md +65 -0
- package/rules/ts/no-non-null-asserted-optional-chain.md +55 -0
- package/rules/ts/no-require-imports.md +54 -0
- package/rules/ts/no-this-alias.md +68 -0
- package/rules/ts/no-unnecessary-type-constraint.md +64 -0
- package/rules/ts/no-unsafe-declaration-merging.md +73 -0
- package/rules/ts/no-unsafe-function-type.md +57 -0
- package/rules/ts/no-unused-expressions.md +61 -0
- package/rules/ts/no-unused-vars.md +68 -0
- package/rules/ts/no-wrapper-object-types.md +49 -0
- package/rules/ts/prefer-as-const.md +47 -0
- package/rules/ts/prefer-namespace-keyword.md +63 -0
- package/rules/ts/triple-slash-reference.md +60 -0
- package/rules/ts/type-only-imports.md +57 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-async-promise-executor
|
|
3
|
+
title: "A Promise executor is not an async function"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the rewrite depends on what the executor does"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-async-promise-executor]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The function passed to `new Promise(...)` is not `async`.
|
|
13
|
+
|
|
14
|
+
**Why:** An error thrown in an async executor doesn't reject the promise, and an executor that needs
|
|
15
|
+
`await` doesn't need the `Promise` wrapper.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
any:
|
|
20
|
+
- pattern: new Promise(async ($$$P) => $$$B)
|
|
21
|
+
- pattern: new Promise(async function ($$$P) { $$$B })
|
|
22
|
+
- pattern: new Promise(async $P => $$$B)
|
|
23
|
+
message: "An async Promise executor loses its errors; await inside a plain async function instead"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## How to fix
|
|
27
|
+
|
|
28
|
+
1. If the executor only awaits and resolves, use the awaited promise directly.
|
|
29
|
+
2. Otherwise make the executor a plain function and handle errors with `reject`.
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
### JavaScript
|
|
34
|
+
|
|
35
|
+
#### Don't
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
const data = new Promise(async (resolve) => {
|
|
39
|
+
resolve(await load());
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Do
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
const data = load();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### JSX
|
|
50
|
+
|
|
51
|
+
#### Don't
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
const data = new Promise(async (resolve) => {
|
|
55
|
+
resolve(await load());
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Do
|
|
60
|
+
|
|
61
|
+
```jsx
|
|
62
|
+
const data = load();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### TypeScript
|
|
66
|
+
|
|
67
|
+
#### Don't
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const data = new Promise(async (resolve) => {
|
|
71
|
+
resolve(await load());
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Do
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const data = load();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### TSX
|
|
82
|
+
|
|
83
|
+
#### Don't
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const data = new Promise(async (resolve) => {
|
|
87
|
+
resolve(await load());
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Do
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
const data = load();
|
|
95
|
+
```
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-case-declarations
|
|
3
|
+
title: "No let, const, function or class directly in a case"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "another case may rely on the shared declaration"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-case-declarations]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
A `let`, `const`, `function` or `class` inside a `case` sits in a block `{ … }` of its own.
|
|
13
|
+
|
|
14
|
+
**Why:** Declarations in a case are scoped to the whole `switch`, so another case can see them
|
|
15
|
+
uninitialised.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
any:
|
|
20
|
+
- kind: lexical_declaration
|
|
21
|
+
- kind: class_declaration
|
|
22
|
+
- kind: function_declaration
|
|
23
|
+
inside:
|
|
24
|
+
stopBy: neighbor
|
|
25
|
+
any: [{ kind: switch_case }, { kind: switch_default }]
|
|
26
|
+
message: "A declaration in a case is visible to the whole switch; wrap the case in braces"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## How to fix
|
|
30
|
+
|
|
31
|
+
1. Wrap the case's statements in `{ … }`.
|
|
32
|
+
2. If another case uses the declaration, move it above the `switch`.
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
### JavaScript
|
|
37
|
+
|
|
38
|
+
#### Don't
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
switch (kind) {
|
|
42
|
+
case "a":
|
|
43
|
+
const n = 1;
|
|
44
|
+
use(n);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### Do
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
switch (kind) {
|
|
53
|
+
case "a": {
|
|
54
|
+
const n = 1;
|
|
55
|
+
use(n);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### JSX
|
|
62
|
+
|
|
63
|
+
#### Don't
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
switch (kind) {
|
|
67
|
+
case "a":
|
|
68
|
+
const n = 1;
|
|
69
|
+
use(n);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Do
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
switch (kind) {
|
|
78
|
+
case "a": {
|
|
79
|
+
const n = 1;
|
|
80
|
+
use(n);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### TypeScript
|
|
87
|
+
|
|
88
|
+
#### Don't
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
switch (kind) {
|
|
92
|
+
case "a":
|
|
93
|
+
const n = 1;
|
|
94
|
+
use(n);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Do
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
switch (kind) {
|
|
103
|
+
case "a": {
|
|
104
|
+
const n = 1;
|
|
105
|
+
use(n);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### TSX
|
|
112
|
+
|
|
113
|
+
#### Don't
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
switch (kind) {
|
|
117
|
+
case "a":
|
|
118
|
+
const n = 1;
|
|
119
|
+
use(n);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Do
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
switch (kind) {
|
|
128
|
+
case "a": {
|
|
129
|
+
const n = 1;
|
|
130
|
+
use(n);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-class-assign
|
|
3
|
+
title: "A class name is not reassigned"
|
|
4
|
+
languages: [javascript, jsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "what the assignment was for is the author's call"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-class-assign]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Code doesn't assign a new value to the name a class declaration binds.
|
|
13
|
+
|
|
14
|
+
**Why:** Reassigning a class name is almost always a mistake, and makes every later use mean
|
|
15
|
+
something else.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
kind: identifier
|
|
20
|
+
where:
|
|
21
|
+
$$MATCH: [write, { binding: class }]
|
|
22
|
+
message: "`$$MATCH` is a class; don't assign to it"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## How to fix
|
|
26
|
+
|
|
27
|
+
1. Assign to a new variable instead of the class name.
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### JavaScript
|
|
32
|
+
|
|
33
|
+
#### Don't
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
class Point {}
|
|
37
|
+
Point = null;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Do
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
class Point {}
|
|
44
|
+
const origin = null;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### JSX
|
|
48
|
+
|
|
49
|
+
#### Don't
|
|
50
|
+
|
|
51
|
+
```jsx
|
|
52
|
+
class Point {}
|
|
53
|
+
Point = null;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Do
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
class Point {}
|
|
60
|
+
const origin = null;
|
|
61
|
+
```
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-compare-neg-zero
|
|
3
|
+
title: "No comparisons against -0"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether `0` or `-0` was meant needs the author"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-compare-neg-zero]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Code doesn't compare a value with `-0` using `==`, `===`, `<` or the other comparison operators.
|
|
13
|
+
|
|
14
|
+
**Why:** These operators treat `-0` and `0` as equal, so the comparison doesn't test what it says.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
match:
|
|
18
|
+
kind: binary_expression
|
|
19
|
+
any:
|
|
20
|
+
- has: { field: right, pattern: "-0" }
|
|
21
|
+
- has: { field: left, pattern: "-0" }
|
|
22
|
+
has:
|
|
23
|
+
field: operator
|
|
24
|
+
regex: ^(==|===|!=|!==|<|>|<=|>=)$
|
|
25
|
+
message: "Comparing with -0 is the same as comparing with 0; use Object.is(x, -0) to test for -0"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## How to fix
|
|
29
|
+
|
|
30
|
+
1. To test for negative zero, use `Object.is(x, -0)`.
|
|
31
|
+
2. To test for zero of either sign, compare with `0`.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
### JavaScript
|
|
36
|
+
|
|
37
|
+
#### Don't
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
if (x === -0) {
|
|
41
|
+
flip();
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Do
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
if (Object.is(x, -0)) {
|
|
49
|
+
flip();
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### JSX
|
|
54
|
+
|
|
55
|
+
#### Don't
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
if (x === -0) {
|
|
59
|
+
flip();
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Do
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
if (Object.is(x, -0)) {
|
|
67
|
+
flip();
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### TypeScript
|
|
72
|
+
|
|
73
|
+
#### Don't
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
if (x === -0) {
|
|
77
|
+
flip();
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Do
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
if (Object.is(x, -0)) {
|
|
85
|
+
flip();
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### TSX
|
|
90
|
+
|
|
91
|
+
#### Don't
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
if (x === -0) {
|
|
95
|
+
flip();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Do
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
if (Object.is(x, -0)) {
|
|
103
|
+
flip();
|
|
104
|
+
}
|
|
105
|
+
```
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-cond-assign
|
|
3
|
+
title: "No assignment in a condition, unless doubly parenthesised"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether a comparison or an assignment was meant needs the author"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-cond-assign]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The condition of an `if`, `while`, `do … while` or `for` is not an assignment, unless it is wrapped
|
|
13
|
+
in a second pair of parentheses to say it's meant.
|
|
14
|
+
|
|
15
|
+
**Why:** `if (a = b)` assigns and tests the result, which is almost always a mistyped `===`.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
kind: assignment_expression
|
|
20
|
+
any:
|
|
21
|
+
- inside:
|
|
22
|
+
stopBy: neighbor
|
|
23
|
+
kind: parenthesized_expression
|
|
24
|
+
inside:
|
|
25
|
+
stopBy: neighbor
|
|
26
|
+
any: [{ kind: if_statement }, { kind: while_statement }, { kind: do_statement }]
|
|
27
|
+
- inside:
|
|
28
|
+
stopBy: neighbor
|
|
29
|
+
kind: expression_statement
|
|
30
|
+
inside: { stopBy: neighbor, kind: for_statement, field: condition }
|
|
31
|
+
message: "An assignment in a condition is usually a mistyped comparison"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How to fix
|
|
35
|
+
|
|
36
|
+
1. If a comparison was meant, use `===`.
|
|
37
|
+
2. If the assignment is meant, wrap it in a second pair of parentheses.
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
### JavaScript
|
|
42
|
+
|
|
43
|
+
#### Don't
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
if (user = admin) {
|
|
47
|
+
grant();
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Do
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
if (user === admin) {
|
|
55
|
+
grant();
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
while ((node = node.next)) {
|
|
61
|
+
visit(node);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### JSX
|
|
66
|
+
|
|
67
|
+
#### Don't
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
if (user = admin) {
|
|
71
|
+
grant();
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Do
|
|
76
|
+
|
|
77
|
+
```jsx
|
|
78
|
+
if (user === admin) {
|
|
79
|
+
grant();
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```jsx
|
|
84
|
+
while ((node = node.next)) {
|
|
85
|
+
visit(node);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### TypeScript
|
|
90
|
+
|
|
91
|
+
#### Don't
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
if (user = admin) {
|
|
95
|
+
grant();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Do
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
if (user === admin) {
|
|
103
|
+
grant();
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
while ((node = node.next)) {
|
|
109
|
+
visit(node);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### TSX
|
|
114
|
+
|
|
115
|
+
#### Don't
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
if (user = admin) {
|
|
119
|
+
grant();
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Do
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
if (user === admin) {
|
|
127
|
+
grant();
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
while ((node = node.next)) {
|
|
133
|
+
visit(node);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-const-assign
|
|
3
|
+
title: "A const is not reassigned"
|
|
4
|
+
languages: [javascript, jsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether the variable should be `let` or the assignment should go is the author's call"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-const-assign]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Code doesn't assign a new value to a `const`.
|
|
13
|
+
|
|
14
|
+
**Why:** Assigning to a `const` throws a TypeError at run time.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
match:
|
|
18
|
+
kind: identifier
|
|
19
|
+
where:
|
|
20
|
+
$$MATCH: [write, { binding: const }]
|
|
21
|
+
message: "`$$MATCH` is a const; assigning to it throws"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## How to fix
|
|
25
|
+
|
|
26
|
+
1. If the value is meant to change, declare it with `let`.
|
|
27
|
+
2. Otherwise assign to a new variable.
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### JavaScript
|
|
32
|
+
|
|
33
|
+
#### Don't
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const total = 0;
|
|
37
|
+
total = 1;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Do
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
let total = 0;
|
|
44
|
+
total = 1;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### JSX
|
|
48
|
+
|
|
49
|
+
#### Don't
|
|
50
|
+
|
|
51
|
+
```jsx
|
|
52
|
+
const total = 0;
|
|
53
|
+
total = 1;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### Do
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
let total = 0;
|
|
60
|
+
total = 1;
|
|
61
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-constant-binary-expression
|
|
3
|
+
title: "No binary expression whose result is fixed"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the intended grouping or comparison needs the author"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-constant-binary-expression]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The left side of `??`, `||` and `&&` is not a value whose nullishness or truthiness is fixed, and
|
|
13
|
+
nothing is compared with a newly created object or with `null` when it can never be `null`.
|
|
14
|
+
|
|
15
|
+
**Why:** Such an expression always gives the same answer, which usually means the author misread
|
|
16
|
+
operator precedence.
|
|
17
|
+
|
|
18
|
+
```codelaw
|
|
19
|
+
native: js/no-constant-binary-expression
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How to fix
|
|
23
|
+
|
|
24
|
+
1. Add the parentheses the expression was meant to have.
|
|
25
|
+
2. Or compare with the value that was meant.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### JavaScript
|
|
30
|
+
|
|
31
|
+
#### Don't
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const total = price + tax ?? 0;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
const total = price + (tax ?? 0);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### JSX
|
|
44
|
+
|
|
45
|
+
#### Don't
|
|
46
|
+
|
|
47
|
+
```jsx
|
|
48
|
+
const total = price + tax ?? 0;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Do
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
const total = price + (tax ?? 0);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### TypeScript
|
|
58
|
+
|
|
59
|
+
#### Don't
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const total = price + tax ?? 0;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Do
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const total = price + (tax ?? 0);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### TSX
|
|
72
|
+
|
|
73
|
+
#### Don't
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const total = price + tax ?? 0;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Do
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const total = price + (tax ?? 0);
|
|
83
|
+
```
|