@typescript-eslint/eslint-plugin 8.28.0 → 8.28.1-alpha.1
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/dist/rules/no-unnecessary-condition.d.ts.map +1 -1
- package/dist/rules/no-unnecessary-condition.js +8 -6
- package/dist/rules/prefer-nullish-coalescing.d.ts +1 -0
- package/dist/rules/prefer-nullish-coalescing.d.ts.map +1 -1
- package/dist/rules/prefer-nullish-coalescing.js +7 -2
- package/dist/rules/use-unknown-in-catch-callback-variable.d.ts.map +1 -1
- package/dist/rules/use-unknown-in-catch-callback-variable.js +0 -1
- package/dist/util/isAssignee.d.ts.map +1 -1
- package/dist/util/isAssignee.js +8 -0
- package/docs/rules/no-unsafe-argument.mdx +3 -3
- package/docs/rules/prefer-nullish-coalescing.mdx +43 -0
- package/package.json +7 -7
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"no-unnecessary-condition.d.ts","sourceRoot":"","sources":["../../src/rules/no-unnecessary-condition.ts"],"names":[],"mappings":"AAyHA,KAAK,iCAAiC,GAAG,OAAO,CAAC;AAEjD,KAAK,2BAA2B,GAAG,QAAQ,GAAG,OAAO,GAAG,uBAAuB,CAAC;AAShF,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,2BAA2B,CAAC,EACxB,2BAA2B,GAC3B,iCAAiC,CAAC;QACtC,sDAAsD,CAAC,EAAE,OAAO,CAAC;QACjE,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B;CACF,CAAC;AAEF,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,iBAAiB,GACjB,eAAe,GACf,cAAc,GACd,kBAAkB,GAClB,+BAA+B,GAC/B,OAAO,GACP,cAAc,GACd,oBAAoB,GACpB,4BAA4B,GAC5B,mBAAmB,GACnB,wBAAwB,CAAC;;AAE7B,
|
1
|
+
{"version":3,"file":"no-unnecessary-condition.d.ts","sourceRoot":"","sources":["../../src/rules/no-unnecessary-condition.ts"],"names":[],"mappings":"AAyHA,KAAK,iCAAiC,GAAG,OAAO,CAAC;AAEjD,KAAK,2BAA2B,GAAG,QAAQ,GAAG,OAAO,GAAG,uBAAuB,CAAC;AAShF,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,2BAA2B,CAAC,EACxB,2BAA2B,GAC3B,iCAAiC,CAAC;QACtC,sDAAsD,CAAC,EAAE,OAAO,CAAC;QACjE,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B;CACF,CAAC;AAEF,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,iBAAiB,GACjB,eAAe,GACf,cAAc,GACd,kBAAkB,GAClB,+BAA+B,GAC/B,OAAO,GACP,cAAc,GACd,oBAAoB,GACpB,4BAA4B,GAC5B,mBAAmB,GACnB,wBAAwB,CAAC;;AAE7B,wBAowBG"}
|
@@ -258,7 +258,7 @@ exports.default = (0, util_1.createRule)({
|
|
258
258
|
// Since typescript array index signature types don't represent the
|
259
259
|
// possibility of out-of-bounds access, if we're indexing into an array
|
260
260
|
// just skip the check, to avoid false positives
|
261
|
-
if (isArrayIndexExpression(expression)) {
|
261
|
+
if (!isNoUncheckedIndexedAccess && isArrayIndexExpression(expression)) {
|
262
262
|
return;
|
263
263
|
}
|
264
264
|
// When checking logical expressions, only check the right side
|
@@ -308,10 +308,11 @@ exports.default = (0, util_1.createRule)({
|
|
308
308
|
// Since typescript array index signature types don't represent the
|
309
309
|
// possibility of out-of-bounds access, if we're indexing into an array
|
310
310
|
// just skip the check, to avoid false positives
|
311
|
-
if (
|
312
|
-
!(node
|
313
|
-
node.
|
314
|
-
|
311
|
+
if (isNoUncheckedIndexedAccess ||
|
312
|
+
(!isArrayIndexExpression(node) &&
|
313
|
+
!(node.type === utils_1.AST_NODE_TYPES.ChainExpression &&
|
314
|
+
node.expression.type !== utils_1.AST_NODE_TYPES.TSNonNullExpression &&
|
315
|
+
optionChainContainsOptionArrayIndex(node.expression)))) {
|
315
316
|
messageId = 'neverNullish';
|
316
317
|
}
|
317
318
|
}
|
@@ -598,7 +599,8 @@ exports.default = (0, util_1.createRule)({
|
|
598
599
|
// Since typescript array index signature types don't represent the
|
599
600
|
// possibility of out-of-bounds access, if we're indexing into an array
|
600
601
|
// just skip the check, to avoid false positives
|
601
|
-
if (
|
602
|
+
if (!isNoUncheckedIndexedAccess &&
|
603
|
+
optionChainContainsOptionArrayIndex(node)) {
|
602
604
|
return;
|
603
605
|
}
|
604
606
|
const nodeToCheck = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
|
@@ -4,6 +4,7 @@ export type Options = [
|
|
4
4
|
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
|
5
5
|
ignoreBooleanCoercion?: boolean;
|
6
6
|
ignoreConditionalTests?: boolean;
|
7
|
+
ignoreIfStatements?: boolean;
|
7
8
|
ignoreMixedLogicalExpressions?: boolean;
|
8
9
|
ignorePrimitives?: {
|
9
10
|
bigint?: boolean;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"prefer-nullish-coalescing.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-nullish-coalescing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAqCnE,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,sDAAsD,CAAC,EAAE,OAAO,CAAC;QACjE,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,6BAA6B,CAAC,EAAE,OAAO,CAAC;QACxC,gBAAgB,CAAC,EACb;YACE,MAAM,CAAC,EAAE,OAAO,CAAC;YACjB,OAAO,CAAC,EAAE,OAAO,CAAC;YAClB,MAAM,CAAC,EAAE,OAAO,CAAC;YACjB,MAAM,CAAC,EAAE,OAAO,CAAC;SAClB,GACD,IAAI,CAAC;QACT,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,mBAAmB,GACnB,6BAA6B,GAC7B,qBAAqB,GACrB,0BAA0B,GAC1B,gBAAgB,CAAC;;AAErB,
|
1
|
+
{"version":3,"file":"prefer-nullish-coalescing.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-nullish-coalescing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAqCnE,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,sDAAsD,CAAC,EAAE,OAAO,CAAC;QACjE,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,6BAA6B,CAAC,EAAE,OAAO,CAAC;QACxC,gBAAgB,CAAC,EACb;YACE,MAAM,CAAC,EAAE,OAAO,CAAC;YACjB,OAAO,CAAC,EAAE,OAAO,CAAC;YAClB,MAAM,CAAC,EAAE,OAAO,CAAC;YACjB,MAAM,CAAC,EAAE,OAAO,CAAC;SAClB,GACD,IAAI,CAAC;QACT,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B;CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,mBAAmB,GACnB,6BAA6B,GAC7B,qBAAqB,GACrB,0BAA0B,GAC1B,gBAAgB,CAAC;;AAErB,wBA8jBG"}
|
@@ -79,6 +79,10 @@ exports.default = (0, util_1.createRule)({
|
|
79
79
|
type: 'boolean',
|
80
80
|
description: 'Whether to ignore cases that are located within a conditional test.',
|
81
81
|
},
|
82
|
+
ignoreIfStatements: {
|
83
|
+
type: 'boolean',
|
84
|
+
description: 'Whether to ignore any if statements that could be simplified by using the nullish coalescing operator.',
|
85
|
+
},
|
82
86
|
ignoreMixedLogicalExpressions: {
|
83
87
|
type: 'boolean',
|
84
88
|
description: 'Whether to ignore any logical or expressions that are part of a mixed logical expression (with `&&`).',
|
@@ -128,6 +132,7 @@ exports.default = (0, util_1.createRule)({
|
|
128
132
|
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
|
129
133
|
ignoreBooleanCoercion: false,
|
130
134
|
ignoreConditionalTests: true,
|
135
|
+
ignoreIfStatements: false,
|
131
136
|
ignoreMixedLogicalExpressions: false,
|
132
137
|
ignorePrimitives: {
|
133
138
|
bigint: false,
|
@@ -138,7 +143,7 @@ exports.default = (0, util_1.createRule)({
|
|
138
143
|
ignoreTernaryTests: false,
|
139
144
|
},
|
140
145
|
],
|
141
|
-
create(context, [{ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, ignoreBooleanCoercion, ignoreConditionalTests, ignoreMixedLogicalExpressions, ignorePrimitives, ignoreTernaryTests, },]) {
|
146
|
+
create(context, [{ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, ignoreBooleanCoercion, ignoreConditionalTests, ignoreIfStatements, ignoreMixedLogicalExpressions, ignorePrimitives, ignoreTernaryTests, },]) {
|
142
147
|
const parserServices = (0, util_1.getParserServices)(context);
|
143
148
|
const compilerOptions = parserServices.program.getCompilerOptions();
|
144
149
|
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
|
@@ -369,7 +374,7 @@ exports.default = (0, util_1.createRule)({
|
|
369
374
|
}
|
370
375
|
},
|
371
376
|
IfStatement(node) {
|
372
|
-
if (node.alternate != null) {
|
377
|
+
if (ignoreIfStatements || node.alternate != null) {
|
373
378
|
return;
|
374
379
|
}
|
375
380
|
let assignmentExpression;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"use-unknown-in-catch-callback-variable.d.ts","sourceRoot":"","sources":["../../src/rules/use-unknown-in-catch-callback-variable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAgBnE,MAAM,MAAM,UAAU,GAClB,wCAAwC,GACxC,oCAAoC,GACpC,YAAY,GACZ,qCAAqC,GACrC,sCAAsC,GACtC,mCAAmC,GACnC,+BAA+B,CAAC;;AAKpC,
|
1
|
+
{"version":3,"file":"use-unknown-in-catch-callback-variable.d.ts","sourceRoot":"","sources":["../../src/rules/use-unknown-in-catch-callback-variable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAgBnE,MAAM,MAAM,UAAU,GAClB,wCAAwC,GACxC,oCAAoC,GACpC,YAAY,GACZ,qCAAqC,GACrC,sCAAsC,GACtC,mCAAmC,GACnC,+BAA+B,CAAC;;AAKpC,wBAkSG"}
|
@@ -46,7 +46,6 @@ exports.default = (0, util_1.createRule)({
|
|
46
46
|
recommended: 'strict',
|
47
47
|
requiresTypeChecking: true,
|
48
48
|
},
|
49
|
-
fixable: 'code',
|
50
49
|
hasSuggestions: true,
|
51
50
|
messages: {
|
52
51
|
addUnknownRestTypeAnnotationSuggestion: 'Add an explicit `: [unknown]` type annotation to the rejection callback rest variable.',
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"isAssignee.d.ts","sourceRoot":"","sources":["../../src/util/isAssignee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIzD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,OAAO,
|
1
|
+
{"version":3,"file":"isAssignee.d.ts","sourceRoot":"","sources":["../../src/util/isAssignee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIzD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,OAAO,CA+DvD"}
|
package/dist/util/isAssignee.js
CHANGED
@@ -38,5 +38,13 @@ function isAssignee(node) {
|
|
38
38
|
isAssignee(parent.parent)) {
|
39
39
|
return true;
|
40
40
|
}
|
41
|
+
// (a[i] as number)++, [...a[i]!] = [0], etc.
|
42
|
+
if ((parent.type === utils_1.AST_NODE_TYPES.TSNonNullExpression ||
|
43
|
+
parent.type === utils_1.AST_NODE_TYPES.TSAsExpression ||
|
44
|
+
parent.type === utils_1.AST_NODE_TYPES.TSTypeAssertion ||
|
45
|
+
parent.type === utils_1.AST_NODE_TYPES.TSSatisfiesExpression) &&
|
46
|
+
isAssignee(parent)) {
|
47
|
+
return true;
|
48
|
+
}
|
41
49
|
return false;
|
42
50
|
}
|
@@ -45,10 +45,10 @@ foo('a', ...tuple2, anyTyped);
|
|
45
45
|
|
46
46
|
declare function bar(arg1: string, arg2: number, ...rest: string[]): void;
|
47
47
|
const x = [1, 2] as [number, ...number[]];
|
48
|
-
|
48
|
+
bar('a', ...x, anyTyped);
|
49
49
|
|
50
50
|
declare function baz(arg1: Set<string>, arg2: Map<string, string>): void;
|
51
|
-
|
51
|
+
baz(new Set<any>(), new Map<any, string>());
|
52
52
|
```
|
53
53
|
|
54
54
|
</TabItem>
|
@@ -67,7 +67,7 @@ const array: string[] = ['a'];
|
|
67
67
|
bar('a', 1, ...array);
|
68
68
|
|
69
69
|
declare function baz(arg1: Set<string>, arg2: Map<string, string>): void;
|
70
|
-
|
70
|
+
baz(new Set<string>(), new Map<string, string>());
|
71
71
|
```
|
72
72
|
|
73
73
|
</TabItem>
|
@@ -118,6 +118,49 @@ c ?? 'a string';
|
|
118
118
|
</TabItem>
|
119
119
|
</Tabs>
|
120
120
|
|
121
|
+
### `ignoreIfStatements`
|
122
|
+
|
123
|
+
{/* insert option description */}
|
124
|
+
|
125
|
+
Examples of code for this rule with `{ ignoreIfStatements: false }`:
|
126
|
+
|
127
|
+
<Tabs>
|
128
|
+
<TabItem value="❌ Incorrect">
|
129
|
+
|
130
|
+
```ts option='{ "ignoreIfStatements": false }'
|
131
|
+
declare let foo: { a: string } | null;
|
132
|
+
declare function makeFoo(): { a: string };
|
133
|
+
|
134
|
+
function lazyInitializeFoo1() {
|
135
|
+
if (!foo) {
|
136
|
+
foo = makeFoo();
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
function lazyInitializeFoo2() {
|
141
|
+
if (!foo) foo = makeFoo();
|
142
|
+
}
|
143
|
+
```
|
144
|
+
|
145
|
+
</TabItem>
|
146
|
+
<TabItem value="✅ Correct">
|
147
|
+
|
148
|
+
```ts option='{ "ignoreIfStatements": false }'
|
149
|
+
declare let foo: { a: string } | null;
|
150
|
+
declare function makeFoo(): { a: string };
|
151
|
+
|
152
|
+
function lazyInitializeFoo1() {
|
153
|
+
foo ??= makeFoo();
|
154
|
+
}
|
155
|
+
|
156
|
+
function lazyInitializeFoo2() {
|
157
|
+
foo ??= makeFoo();
|
158
|
+
}
|
159
|
+
```
|
160
|
+
|
161
|
+
</TabItem>
|
162
|
+
</Tabs>
|
163
|
+
|
121
164
|
### `ignoreConditionalTests`
|
122
165
|
|
123
166
|
{/* insert option description */}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@typescript-eslint/eslint-plugin",
|
3
|
-
"version": "8.28.
|
3
|
+
"version": "8.28.1-alpha.1",
|
4
4
|
"description": "TypeScript plugin for ESLint",
|
5
5
|
"files": [
|
6
6
|
"dist",
|
@@ -62,10 +62,10 @@
|
|
62
62
|
},
|
63
63
|
"dependencies": {
|
64
64
|
"@eslint-community/regexpp": "^4.10.0",
|
65
|
-
"@typescript-eslint/scope-manager": "8.28.
|
66
|
-
"@typescript-eslint/type-utils": "8.28.
|
67
|
-
"@typescript-eslint/utils": "8.28.
|
68
|
-
"@typescript-eslint/visitor-keys": "8.28.
|
65
|
+
"@typescript-eslint/scope-manager": "8.28.1-alpha.1",
|
66
|
+
"@typescript-eslint/type-utils": "8.28.1-alpha.1",
|
67
|
+
"@typescript-eslint/utils": "8.28.1-alpha.1",
|
68
|
+
"@typescript-eslint/visitor-keys": "8.28.1-alpha.1",
|
69
69
|
"graphemer": "^1.4.0",
|
70
70
|
"ignore": "^5.3.1",
|
71
71
|
"natural-compare": "^1.4.0",
|
@@ -76,8 +76,8 @@
|
|
76
76
|
"@types/marked": "^5.0.2",
|
77
77
|
"@types/mdast": "^4.0.3",
|
78
78
|
"@types/natural-compare": "*",
|
79
|
-
"@typescript-eslint/rule-schema-to-typescript-types": "8.28.
|
80
|
-
"@typescript-eslint/rule-tester": "8.28.
|
79
|
+
"@typescript-eslint/rule-schema-to-typescript-types": "8.28.1-alpha.1",
|
80
|
+
"@typescript-eslint/rule-tester": "8.28.1-alpha.1",
|
81
81
|
"ajv": "^6.12.6",
|
82
82
|
"cross-env": "^7.0.3",
|
83
83
|
"cross-fetch": "*",
|