@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,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unexpected-multiline
|
|
3
|
+
title: "A line break doesn't silently join two lines into one expression"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether the lines were meant to join can only be known from intent"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unexpected-multiline]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
A line that starts with `(`, `[` or a template literal does not continue the expression on the line
|
|
13
|
+
before it without a semicolon.
|
|
14
|
+
|
|
15
|
+
**Why:** Without semicolons, JavaScript joins such lines: `a\n(b)` is the call `a(b)`, which is
|
|
16
|
+
rarely what was written.
|
|
17
|
+
|
|
18
|
+
```codelaw
|
|
19
|
+
native: js/no-unexpected-multiline
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How to fix
|
|
23
|
+
|
|
24
|
+
1. If the lines are separate statements, end the first with a semicolon.
|
|
25
|
+
2. If they are one expression, move the `(` or `[` onto the first line.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### JavaScript
|
|
30
|
+
|
|
31
|
+
#### Don't
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const total = sum
|
|
35
|
+
(items).forEach(log);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### Do
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
const total = sum;
|
|
42
|
+
(items).forEach(log);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### JSX
|
|
46
|
+
|
|
47
|
+
#### Don't
|
|
48
|
+
|
|
49
|
+
```jsx
|
|
50
|
+
const total = sum
|
|
51
|
+
(items).forEach(log);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Do
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
const total = sum;
|
|
58
|
+
(items).forEach(log);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### TypeScript
|
|
62
|
+
|
|
63
|
+
#### Don't
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const total = sum
|
|
67
|
+
(items).forEach(log);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Do
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const total = sum;
|
|
74
|
+
(items).forEach(log);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### TSX
|
|
78
|
+
|
|
79
|
+
#### Don't
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const total = sum
|
|
83
|
+
(items).forEach(log);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Do
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
const total = sum;
|
|
90
|
+
(items).forEach(log);
|
|
91
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unreachable
|
|
3
|
+
title: "No code after a return, throw, break or continue"
|
|
4
|
+
languages: [javascript, jsx]
|
|
5
|
+
fix: suggest
|
|
6
|
+
fix_reason: "deleting the code is right only when it was really dead, not misplaced"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unreachable]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Statements after an unconditional `return`, `throw`, `break` or `continue` in the same block are
|
|
13
|
+
removed or moved; hoisted function declarations and uninitialised `var`s are allowed.
|
|
14
|
+
|
|
15
|
+
**Why:** Unreachable code never runs, so it misleads every reader who assumes it does.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
native: js/no-unreachable
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
### JavaScript
|
|
24
|
+
|
|
25
|
+
#### Don't
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
function total(items) {
|
|
29
|
+
return items.length;
|
|
30
|
+
log(items);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### Do
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
function total(items) {
|
|
38
|
+
return items.length;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### JSX
|
|
43
|
+
|
|
44
|
+
#### Don't
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
function total(items) {
|
|
48
|
+
return items.length;
|
|
49
|
+
log(items);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Do
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
function total(items) {
|
|
57
|
+
return items.length;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unsafe-finally
|
|
3
|
+
title: "No return, throw, break or continue in finally"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "what should happen to the try block's result is a decision"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unsafe-finally]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
A `finally` block doesn't end the function or loop with `return`, `throw`, `break` or `continue`.
|
|
13
|
+
|
|
14
|
+
**Why:** Control flow in `finally` silently replaces whatever the `try` or `catch` block returned or
|
|
15
|
+
threw.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
any:
|
|
20
|
+
- kind: return_statement
|
|
21
|
+
- kind: throw_statement
|
|
22
|
+
- kind: break_statement
|
|
23
|
+
- kind: continue_statement
|
|
24
|
+
inside:
|
|
25
|
+
kind: finally_clause
|
|
26
|
+
stopBy:
|
|
27
|
+
any: [{kind: function_declaration}, {kind: function_expression}, {kind: arrow_function}, {kind: method_definition}, {kind: generator_function_declaration}, {kind: generator_function}, { kind: class_declaration }]
|
|
28
|
+
not:
|
|
29
|
+
all:
|
|
30
|
+
- any: [{ kind: break_statement }, { kind: continue_statement }]
|
|
31
|
+
- inside:
|
|
32
|
+
stopBy: { kind: finally_clause }
|
|
33
|
+
any: [{ kind: for_statement }, { kind: for_in_statement }, { kind: while_statement }, { kind: do_statement }, { kind: switch_statement }]
|
|
34
|
+
message: "Control flow in `finally` overrides the try block's return or exception"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## How to fix
|
|
38
|
+
|
|
39
|
+
1. Move the `return` or `throw` out of `finally` into the `try` or `catch` block.
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
### JavaScript
|
|
44
|
+
|
|
45
|
+
#### Don't
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
function load() {
|
|
49
|
+
try {
|
|
50
|
+
return fetchAll();
|
|
51
|
+
} finally {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Do
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
function load() {
|
|
61
|
+
try {
|
|
62
|
+
return fetchAll();
|
|
63
|
+
} finally {
|
|
64
|
+
cleanup();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### JSX
|
|
70
|
+
|
|
71
|
+
#### Don't
|
|
72
|
+
|
|
73
|
+
```jsx
|
|
74
|
+
function load() {
|
|
75
|
+
try {
|
|
76
|
+
return fetchAll();
|
|
77
|
+
} finally {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Do
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
function load() {
|
|
87
|
+
try {
|
|
88
|
+
return fetchAll();
|
|
89
|
+
} finally {
|
|
90
|
+
cleanup();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### TypeScript
|
|
96
|
+
|
|
97
|
+
#### Don't
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
function load() {
|
|
101
|
+
try {
|
|
102
|
+
return fetchAll();
|
|
103
|
+
} finally {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Do
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
function load() {
|
|
113
|
+
try {
|
|
114
|
+
return fetchAll();
|
|
115
|
+
} finally {
|
|
116
|
+
cleanup();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### TSX
|
|
122
|
+
|
|
123
|
+
#### Don't
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
function load() {
|
|
127
|
+
try {
|
|
128
|
+
return fetchAll();
|
|
129
|
+
} finally {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Do
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
function load() {
|
|
139
|
+
try {
|
|
140
|
+
return fetchAll();
|
|
141
|
+
} finally {
|
|
142
|
+
cleanup();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unsafe-negation
|
|
3
|
+
title: "No negating the left side of in or instanceof"
|
|
4
|
+
languages: [javascript, jsx]
|
|
5
|
+
fix: suggest
|
|
6
|
+
fix_reason: "code that really meant `(!a) in b` would change"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unsafe-negation]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
`!` before `a in b` or `a instanceof B` wraps the whole test in parentheses.
|
|
13
|
+
|
|
14
|
+
**Why:** `!a in b` means `(!a) in b`, which tests whether `true` or `false` is a key — never what
|
|
15
|
+
was meant.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
match:
|
|
19
|
+
kind: binary_expression
|
|
20
|
+
all:
|
|
21
|
+
- has: { field: operator, regex: ^(in|instanceof)$ }
|
|
22
|
+
- has:
|
|
23
|
+
field: left
|
|
24
|
+
kind: unary_expression
|
|
25
|
+
regex: ^!
|
|
26
|
+
pattern: $NEG
|
|
27
|
+
has: { field: argument, pattern: $A }
|
|
28
|
+
message: "`!` applies to `$A`, not to the whole test; wrap the test in parentheses"
|
|
29
|
+
fix:
|
|
30
|
+
- insert-before: "!("
|
|
31
|
+
- replace: { target: $NEG, with: "$A" }
|
|
32
|
+
- insert-after: ")"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
### JavaScript
|
|
38
|
+
|
|
39
|
+
#### Don't
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
if (!key in cache) {
|
|
43
|
+
load(key);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### Do
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
if (!(key in cache)) {
|
|
51
|
+
load(key);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### JSX
|
|
56
|
+
|
|
57
|
+
#### Don't
|
|
58
|
+
|
|
59
|
+
```jsx
|
|
60
|
+
if (!key in cache) {
|
|
61
|
+
load(key);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Do
|
|
66
|
+
|
|
67
|
+
```jsx
|
|
68
|
+
if (!(key in cache)) {
|
|
69
|
+
load(key);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unsafe-optional-chaining
|
|
3
|
+
title: "No ?. chain used where undefined throws"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the right fallback value depends on the code"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unsafe-optional-chaining]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
A `?.` chain, which can evaluate to `undefined`, is not called through parentheses, constructed,
|
|
13
|
+
spread into an array or call, destructured, iterated with `for … of`, used on the right of `in` or
|
|
14
|
+
`instanceof`, or extended.
|
|
15
|
+
|
|
16
|
+
**Why:** In those places `undefined` throws a TypeError, which defeats the point of `?.`.
|
|
17
|
+
|
|
18
|
+
```codelaw
|
|
19
|
+
native: js/no-unsafe-optional-chaining
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How to fix
|
|
23
|
+
|
|
24
|
+
1. Give the chain a fallback with `??`.
|
|
25
|
+
2. Or move the `?.` so that it covers the operation that can fail.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### JavaScript
|
|
30
|
+
|
|
31
|
+
#### Don't
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const { name } = user?.profile;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
const { name } = user?.profile ?? {};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### JSX
|
|
44
|
+
|
|
45
|
+
#### Don't
|
|
46
|
+
|
|
47
|
+
```jsx
|
|
48
|
+
const { name } = user?.profile;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Do
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
const { name } = user?.profile ?? {};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### TypeScript
|
|
58
|
+
|
|
59
|
+
#### Don't
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const { name } = user?.profile;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Do
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const { name } = user?.profile ?? {};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### TSX
|
|
72
|
+
|
|
73
|
+
#### Don't
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const { name } = user?.profile;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Do
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const { name } = user?.profile ?? {};
|
|
83
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unused-labels
|
|
3
|
+
title: "Every label is used"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: auto
|
|
6
|
+
stability: preview
|
|
7
|
+
ported_from: [eslint/no-unused-labels]
|
|
8
|
+
since: 0.1.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Every statement label is the target of a `break` or `continue`.
|
|
12
|
+
|
|
13
|
+
**Why:** An unused label is leftover from a refactor and makes the reader look for a jump that isn't
|
|
14
|
+
there.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
match:
|
|
18
|
+
kind: labeled_statement
|
|
19
|
+
all:
|
|
20
|
+
- has: { field: label, pattern: $L }
|
|
21
|
+
- has: { field: body, pattern: $BODY }
|
|
22
|
+
not:
|
|
23
|
+
has:
|
|
24
|
+
stopBy: end
|
|
25
|
+
any: [{ pattern: "break $L;" }, { pattern: "continue $L;" }]
|
|
26
|
+
message: "The label `$L` is never used"
|
|
27
|
+
fix: "$BODY"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
|
|
32
|
+
### JavaScript
|
|
33
|
+
|
|
34
|
+
#### Don't
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
outer: for (const row of rows) {
|
|
38
|
+
draw(row);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Do
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
for (const row of rows) {
|
|
46
|
+
draw(row);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### JSX
|
|
51
|
+
|
|
52
|
+
#### Don't
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
outer: for (const row of rows) {
|
|
56
|
+
draw(row);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### Do
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
for (const row of rows) {
|
|
64
|
+
draw(row);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### TypeScript
|
|
69
|
+
|
|
70
|
+
#### Don't
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
outer: for (const row of rows) {
|
|
74
|
+
draw(row);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Do
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
for (const row of rows) {
|
|
82
|
+
draw(row);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### TSX
|
|
87
|
+
|
|
88
|
+
#### Don't
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
outer: for (const row of rows) {
|
|
92
|
+
draw(row);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Do
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
for (const row of rows) {
|
|
100
|
+
draw(row);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: js/no-unused-private-class-members
|
|
3
|
+
title: "Every private class member is read"
|
|
4
|
+
languages: [javascript, jsx, typescript, tsx]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "removing a member may also remove writes that matter, so it's a reader's call"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [eslint/no-unused-private-class-members]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
A private field, method or accessor (`#name`) is read somewhere in its class; only being written
|
|
13
|
+
doesn't count.
|
|
14
|
+
|
|
15
|
+
**Why:** A private member nothing reads is dead code, since nothing outside the class can reach it.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
native: js/no-unused-private-class-members
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## How to fix
|
|
22
|
+
|
|
23
|
+
1. Check that nothing needs the member's value.
|
|
24
|
+
2. Remove the member and the writes to it, or read it where it was meant to be used.
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### JavaScript
|
|
29
|
+
|
|
30
|
+
#### Don't
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
class Counter {
|
|
34
|
+
#count = 0;
|
|
35
|
+
#unused = 1;
|
|
36
|
+
get value() {
|
|
37
|
+
return this.#count;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Do
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
class Counter {
|
|
46
|
+
#count = 0;
|
|
47
|
+
get value() {
|
|
48
|
+
return this.#count;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### JSX
|
|
54
|
+
|
|
55
|
+
#### Don't
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
class Counter {
|
|
59
|
+
#count = 0;
|
|
60
|
+
#unused = 1;
|
|
61
|
+
get value() {
|
|
62
|
+
return this.#count;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### Do
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
class Counter {
|
|
71
|
+
#count = 0;
|
|
72
|
+
get value() {
|
|
73
|
+
return this.#count;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### TypeScript
|
|
79
|
+
|
|
80
|
+
#### Don't
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
class Counter {
|
|
84
|
+
#count = 0;
|
|
85
|
+
#unused = 1;
|
|
86
|
+
get value() {
|
|
87
|
+
return this.#count;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Do
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
class Counter {
|
|
96
|
+
#count = 0;
|
|
97
|
+
get value() {
|
|
98
|
+
return this.#count;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### TSX
|
|
104
|
+
|
|
105
|
+
#### Don't
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
class Counter {
|
|
109
|
+
#count = 0;
|
|
110
|
+
#unused = 1;
|
|
111
|
+
get value() {
|
|
112
|
+
return this.#count;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Do
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
class Counter {
|
|
121
|
+
#count = 0;
|
|
122
|
+
get value() {
|
|
123
|
+
return this.#count;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|