@typescript-eslint/eslint-plugin 8.70.1-alpha.14 → 8.70.1-alpha.3

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.
@@ -77,18 +77,7 @@ exports.default = (0, util_1.createRule)({
77
77
  messageId: 'removeAwait',
78
78
  fix(fixer) {
79
79
  const awaitKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression'));
80
- const awaitTokenRemovalRange = (0, util_1.getAwaitTokenRemovalRange)(context.sourceCode, awaitKeyword);
81
- const awaitRemovalFix = fixer.removeRange(awaitTokenRemovalRange);
82
- const firstOperandToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(awaitKeyword), util_1.NullThrowsReasons.MissingToken('operand', 'await expression'));
83
- if ((0, util_1.isStartOfArrowFunctionBodyNeedingParentheses)(node, firstOperandToken, context.sourceCode) ||
84
- (0, util_1.isStartOfExpressionStatementNeedingParentheses)(node, firstOperandToken)) {
85
- return [
86
- awaitRemovalFix,
87
- fixer.insertTextBefore(awaitArgumentEsNode, '('),
88
- fixer.insertTextAfter(awaitArgumentEsNode, ')'),
89
- ];
90
- }
91
- return awaitRemovalFix;
80
+ return fixer.remove(awaitKeyword);
92
81
  },
93
82
  },
94
83
  ],
@@ -146,7 +135,7 @@ exports.default = (0, util_1.createRule)({
146
135
  messageId: 'convertToOrdinaryFor',
147
136
  fix(fixer) {
148
137
  const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'for await loop'));
149
- return fixer.removeRange((0, util_1.getAwaitTokenRemovalRange)(context.sourceCode, awaitToken));
138
+ return fixer.remove(awaitToken);
150
139
  },
151
140
  },
152
141
  ],
@@ -179,7 +168,7 @@ exports.default = (0, util_1.createRule)({
179
168
  messageId: 'removeAwait',
180
169
  fix(fixer) {
181
170
  const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await using'));
182
- return fixer.removeRange((0, util_1.getAwaitTokenRemovalRange)(context.sourceCode, awaitToken));
171
+ return fixer.remove(awaitToken);
183
172
  },
184
173
  },
185
174
  }),
@@ -155,14 +155,6 @@ exports.default = (0, util_1.createRule)({
155
155
  return fixer.replaceText(node.parent, 'PropertyKey');
156
156
  };
157
157
  }
158
- function createUnknownFixer(node) {
159
- return (fixer) => {
160
- return fixer.replaceText(node, node.parent.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation &&
161
- isNodeRestElementInFunction(node.parent.parent)
162
- ? 'unknown[]'
163
- : 'unknown');
164
- };
165
- }
166
158
  return {
167
159
  TSAnyKeyword(node) {
168
160
  const isKeyofAny = isNodeWithinKeyofAny(node);
@@ -181,7 +173,7 @@ exports.default = (0, util_1.createRule)({
181
173
  : [
182
174
  {
183
175
  messageId: 'suggestUnknown',
184
- fix: createUnknownFixer(node),
176
+ fix: fixer => fixer.replaceText(node, 'unknown'),
185
177
  },
186
178
  {
187
179
  messageId: 'suggestNever',
@@ -192,7 +184,7 @@ exports.default = (0, util_1.createRule)({
192
184
  if (fixToUnknown) {
193
185
  fixOrSuggest.fix = isKeyofAny
194
186
  ? createPropertyKeyFixer(node)
195
- : createUnknownFixer(node);
187
+ : fixer => fixer.replaceText(node, 'unknown');
196
188
  }
197
189
  context.report({
198
190
  node,
@@ -63,12 +63,8 @@ exports.default = (0, util_1.createRule)({
63
63
  type.getCallSignatures().length === 0 &&
64
64
  type.getConstructSignatures().length === 0 &&
65
65
  // Types still awaiting type arguments, such as `Record<T, unknown>`
66
- // inside a generic declaration, also have no members yet. Every
67
- // primitive is assignable to `{}`, so probing with more than one of
68
- // them rules those out: a mapped type whose keys are not resolved yet,
69
- // such as `{ [K in Keys<T>]: K }`, accepts `number` but not `string`.
70
- checker.isTypeAssignableTo(checker.getNumberType(), type) &&
71
- checker.isTypeAssignableTo(checker.getStringType(), type));
66
+ // inside a generic declaration, also have no members yet.
67
+ checker.isTypeAssignableTo(checker.getNumberType(), type));
72
68
  }
73
69
  function containsEmptyObjectType(type) {
74
70
  return (isEmptyObjectType(type) ||
@@ -84,11 +84,6 @@ exports.default = (0, util_1.createRule)({
84
84
  if (inner.type === utils_1.AST_NODE_TYPES.Literal && inner.value === 0) {
85
85
  return;
86
86
  }
87
- // `void (x = value)` discards the assignment result so the
88
- // expression evaluates to undefined (e.g. `() => void (x = 1)`).
89
- if (inner.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
90
- return;
91
- }
92
87
  const tsArgument = services.esTreeNodeToTSNodeMap.get(node.argument);
93
88
  const argType = services.getTypeAtLocation(node.argument);
94
89
  // Allow `void promiseValue` so this rule does not fight no-floating-promises.
@@ -98,7 +98,7 @@ exports.default = (0, util_1.createRule)({
98
98
  }
99
99
  function getMapSpreadSuggestions(node, type) {
100
100
  const types = tsutils.unionConstituents(type);
101
- if (types.some(t => !isIterableMap(services.program, t))) {
101
+ if (types.some(t => !isMap(services.program, t))) {
102
102
  return null;
103
103
  }
104
104
  if (node.parent.type === utils_1.AST_NODE_TYPES.ObjectExpression &&
@@ -252,9 +252,6 @@ function isClassDeclaration(type) {
252
252
  function isMap(program, type) {
253
253
  return isTypeRecurser(type, t => (0, util_1.isBuiltinSymbolLike)(program, t, ['Map', 'ReadonlyMap', 'WeakMap']));
254
254
  }
255
- function isIterableMap(program, type) {
256
- return isTypeRecurser(type, t => (0, util_1.isBuiltinSymbolLike)(program, t, ['Map', 'ReadonlyMap']));
257
- }
258
255
  function isTypeRecurser(type, predicate) {
259
256
  if (type.isUnionOrIntersection()) {
260
257
  return type.types.some(t => isTypeRecurser(t, predicate));
@@ -178,7 +178,7 @@ exports.default = (0, util_1.createRule)({
178
178
  }
179
179
  if (((0, util_1.isTypeFlagSet)(uncast, ts.TypeFlags.NonPrimitive) &&
180
180
  !(0, util_1.isTypeFlagSet)(cast, ts.TypeFlags.NonPrimitive)) ||
181
- hasIndexSignature(uncast) !== hasIndexSignature(cast) ||
181
+ (hasIndexSignature(uncast) && !hasIndexSignature(cast)) ||
182
182
  containsAny(uncast) ||
183
183
  containsAny(cast) ||
184
184
  (containsTypeVariable(cast) && !containsTypeVariable(uncast))) {
@@ -587,8 +587,11 @@ exports.default = (0, util_1.createRule)({
587
587
  // is parsed as a block body. In those positions the operand must be
588
588
  // wrapped in parentheses to stay an expression.
589
589
  const firstOperandToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(closingAngleBracket), util_1.NullThrowsReasons.MissingToken('operand', 'type assertion'));
590
- const needsParens = (0, util_1.isStartOfExpressionStatementNeedingParentheses)(node, firstOperandToken) ||
591
- (0, util_1.isStartOfArrowFunctionBodyNeedingParentheses)(node, firstOperandToken, context.sourceCode);
590
+ const breaksExpressionStatement = ['{', 'function', 'class'].includes(firstOperandToken.value) &&
591
+ (0, util_1.isStartOfExpressionStatement)(node);
592
+ const breaksArrowFunctionBody = firstOperandToken.value === '{' &&
593
+ (0, util_1.isStartOfArrowFunctionBody)(node, context.sourceCode);
594
+ const needsParens = breaksExpressionStatement || breaksArrowFunctionBody;
592
595
  const fixes = [];
593
596
  if (needsParens) {
594
597
  fixes.push(fixer.insertTextBefore(node, '('));
@@ -211,10 +211,20 @@ exports.default = (0, util_1.createRule)({
211
211
  /* istanbul ignore if */ if (!awaitToken) {
212
212
  return null;
213
213
  }
214
- const awaitTokenRemovalRange = (0, util_1.getAwaitTokenRemovalRange)(context.sourceCode, awaitToken);
215
- const awaitRemovalFix = fixer.removeRange(awaitTokenRemovalRange);
214
+ const startAt = awaitToken.range[0];
215
+ let endAt = awaitToken.range[1];
216
+ // Also remove any extraneous whitespace after `await`, if there is any.
217
+ const nextToken = context.sourceCode.getTokenAfter(awaitToken, {
218
+ includeComments: true,
219
+ });
220
+ if (nextToken) {
221
+ endAt = nextToken.range[0];
222
+ }
223
+ const awaitRemovalFix = fixer.removeRange([startAt, endAt]);
216
224
  const firstOperandToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(awaitToken), util_1.NullThrowsReasons.MissingToken('operand', 'await expression'));
217
- if ((0, util_1.isStartOfArrowFunctionBodyNeedingParentheses)(node, firstOperandToken, context.sourceCode)) {
225
+ const shouldWrapInParentheses = (0, util_1.isOpeningBraceToken)(firstOperandToken) &&
226
+ (0, util_1.isStartOfArrowFunctionBody)(node, context.sourceCode);
227
+ if (shouldWrapInParentheses) {
218
228
  return [
219
229
  awaitRemovalFix,
220
230
  fixer.insertTextBefore(node.argument, '('),
@@ -4,7 +4,6 @@ export * from './baseTypeUtils';
4
4
  export * from './collectUnusedVariables';
5
5
  export * from './createRule';
6
6
  export * from './FunctionSignature';
7
- export * from './getAwaitTokenRemovalRange';
8
7
  export * from './getBaseTypesOfClassMember';
9
8
  export * from './getFixOrSuggest';
10
9
  export * from './getFunctionHeadLoc';
@@ -20,9 +19,8 @@ export * from './isAssignee';
20
19
  export * from './isConditionalTest';
21
20
  export * from './isNodeEqual';
22
21
  export * from './isNullLiteral';
23
- export * from './isStartOfArrowFunctionBodyNeedingParentheses';
22
+ export * from './isStartOfArrowFunctionBody';
24
23
  export * from './isStartOfExpressionStatement';
25
- export * from './isStartOfExpressionStatementNeedingParentheses';
26
24
  export * from './isUndefinedIdentifier';
27
25
  export * from './misc';
28
26
  export * from './needsPrecedingSemiColon';
@@ -21,7 +21,6 @@ __exportStar(require("./baseTypeUtils"), exports);
21
21
  __exportStar(require("./collectUnusedVariables"), exports);
22
22
  __exportStar(require("./createRule"), exports);
23
23
  __exportStar(require("./FunctionSignature"), exports);
24
- __exportStar(require("./getAwaitTokenRemovalRange"), exports);
25
24
  __exportStar(require("./getBaseTypesOfClassMember"), exports);
26
25
  __exportStar(require("./getFixOrSuggest"), exports);
27
26
  __exportStar(require("./getFunctionHeadLoc"), exports);
@@ -37,9 +36,8 @@ __exportStar(require("./isAssignee"), exports);
37
36
  __exportStar(require("./isConditionalTest"), exports);
38
37
  __exportStar(require("./isNodeEqual"), exports);
39
38
  __exportStar(require("./isNullLiteral"), exports);
40
- __exportStar(require("./isStartOfArrowFunctionBodyNeedingParentheses"), exports);
39
+ __exportStar(require("./isStartOfArrowFunctionBody"), exports);
41
40
  __exportStar(require("./isStartOfExpressionStatement"), exports);
42
- __exportStar(require("./isStartOfExpressionStatementNeedingParentheses"), exports);
43
41
  __exportStar(require("./isUndefinedIdentifier"), exports);
44
42
  __exportStar(require("./misc"), exports);
45
43
  __exportStar(require("./needsPrecedingSemiColon"), exports);
@@ -0,0 +1,2 @@
1
+ import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
+ export declare function isStartOfArrowFunctionBody(node: TSESTree.Node, sourceCode: TSESLint.SourceCode): boolean;
@@ -1,12 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isStartOfArrowFunctionBodyNeedingParentheses = isStartOfArrowFunctionBodyNeedingParentheses;
3
+ exports.isStartOfArrowFunctionBody = isStartOfArrowFunctionBody;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const astUtils_1 = require("./astUtils");
6
- function isStartOfArrowFunctionBodyNeedingParentheses(node, firstToken, sourceCode) {
7
- return ((0, astUtils_1.isOpeningBraceToken)(firstToken) &&
8
- isStartOfArrowFunctionBody(node, sourceCode));
9
- }
10
6
  function isStartOfArrowFunctionBody(node, sourceCode) {
11
7
  let current = node;
12
8
  while (true) {
@@ -27,4 +23,4 @@ function isStartOfArrowFunctionBody(node, sourceCode) {
27
23
  current = parent;
28
24
  }
29
25
  }
30
- //# sourceMappingURL=isStartOfArrowFunctionBodyNeedingParentheses.js.map
26
+ //# sourceMappingURL=isStartOfArrowFunctionBody.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.70.1-alpha.14",
3
+ "version": "8.70.1-alpha.3",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -47,10 +47,10 @@
47
47
  ],
48
48
  "dependencies": {
49
49
  "@eslint-community/regexpp": "^4.12.2",
50
- "@typescript-eslint/scope-manager": "8.70.1-alpha.14",
51
- "@typescript-eslint/type-utils": "8.70.1-alpha.14",
52
- "@typescript-eslint/utils": "8.70.1-alpha.14",
53
- "@typescript-eslint/visitor-keys": "8.70.1-alpha.14",
50
+ "@typescript-eslint/scope-manager": "8.70.1-alpha.3",
51
+ "@typescript-eslint/type-utils": "8.70.1-alpha.3",
52
+ "@typescript-eslint/utils": "8.70.1-alpha.3",
53
+ "@typescript-eslint/visitor-keys": "8.70.1-alpha.3",
54
54
  "ignore": "^7.0.5",
55
55
  "natural-compare": "^1.4.0",
56
56
  "ts-api-utils": "^2.5.0"
@@ -60,8 +60,8 @@
60
60
  "@types/mdast": "^4.0.4",
61
61
  "@types/natural-compare": "^1.4.3",
62
62
  "@types/react": "^18.3.21",
63
- "@typescript-eslint/rule-schema-to-typescript-types": "8.70.1-alpha.14",
64
- "@typescript-eslint/rule-tester": "8.70.1-alpha.14",
63
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.70.1-alpha.3",
64
+ "@typescript-eslint/rule-tester": "8.70.1-alpha.3",
65
65
  "@typescript/native": "npm:typescript@^7.0.2",
66
66
  "@vitest/coverage-v8": "^4.0.18",
67
67
  "ajv": "^6.12.6",
@@ -81,7 +81,7 @@
81
81
  "vitest": "^4.0.18"
82
82
  },
83
83
  "peerDependencies": {
84
- "@typescript-eslint/parser": "^8.70.1-alpha.14",
84
+ "@typescript-eslint/parser": "^8.70.1-alpha.3",
85
85
  "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
86
86
  "typescript": ">=4.8.4 <6.1.0"
87
87
  },
@@ -1,4 +0,0 @@
1
- import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
- export declare function getAwaitTokenRemovalRange(sourceCode: TSESLint.SourceCode, awaitToken: TSESTree.IdentifierToken & {
3
- value: 'await';
4
- }): TSESTree.Range;
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAwaitTokenRemovalRange = getAwaitTokenRemovalRange;
4
- function getAwaitTokenRemovalRange(sourceCode, awaitToken) {
5
- const startAt = awaitToken.range[0];
6
- let endAt = awaitToken.range[1];
7
- const nextToken = sourceCode.getTokenAfter(awaitToken, {
8
- includeComments: true,
9
- });
10
- /* istanbul ignore else */ if (nextToken) {
11
- endAt = nextToken.range[0];
12
- }
13
- return [startAt, endAt];
14
- }
15
- //# sourceMappingURL=getAwaitTokenRemovalRange.js.map
@@ -1,2 +0,0 @@
1
- import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
- export declare function isStartOfArrowFunctionBodyNeedingParentheses(node: TSESTree.Node, firstToken: TSESTree.Token, sourceCode: TSESLint.SourceCode): boolean;
@@ -1,2 +0,0 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- export declare function isStartOfExpressionStatementNeedingParentheses(node: TSESTree.Node, firstToken: TSESTree.Token): boolean;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isStartOfExpressionStatementNeedingParentheses = isStartOfExpressionStatementNeedingParentheses;
4
- const isStartOfExpressionStatement_1 = require("./isStartOfExpressionStatement");
5
- function isStartOfExpressionStatementNeedingParentheses(node, firstToken) {
6
- return (['{', 'class', 'function'].includes(firstToken.value) &&
7
- (0, isStartOfExpressionStatement_1.isStartOfExpressionStatement)(node));
8
- }
9
- //# sourceMappingURL=isStartOfExpressionStatementNeedingParentheses.js.map