@typescript-eslint/eslint-plugin 8.67.1-alpha.3 → 8.67.1-alpha.5

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.
@@ -1,4 +1,3 @@
1
- import type { TSESLint } from '@typescript-eslint/utils';
2
1
  export type Options = [
3
2
  {
4
3
  checkLiteralConstAssertions?: boolean;
@@ -6,7 +5,7 @@ export type Options = [
6
5
  }
7
6
  ];
8
7
  export type MessageIds = 'contextuallyUnnecessary' | 'unnecessaryAssertion';
9
- declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
8
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
10
9
  name: string;
11
10
  };
12
11
  export default _default;
@@ -37,42 +37,6 @@ const utils_1 = require("@typescript-eslint/utils");
37
37
  const tsutils = __importStar(require("ts-api-utils"));
38
38
  const ts = __importStar(require("typescript"));
39
39
  const util_1 = require("../util");
40
- function isAtExpressionStatementStart(node) {
41
- let current = node;
42
- while (true) {
43
- const { parent } = current;
44
- if (parent == null) {
45
- return false;
46
- }
47
- if (parent.range[0] !== current.range[0]) {
48
- return false;
49
- }
50
- if (parent.type === utils_1.AST_NODE_TYPES.ExpressionStatement) {
51
- return true;
52
- }
53
- current = parent;
54
- }
55
- }
56
- function isAtArrowFunctionBodyStart(node, sourceCode) {
57
- let current = node;
58
- while (true) {
59
- if ((0, util_1.isParenthesized)(current, sourceCode)) {
60
- return false;
61
- }
62
- const { parent } = current;
63
- if (parent == null) {
64
- return false;
65
- }
66
- if (parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
67
- parent.body === current) {
68
- return true;
69
- }
70
- if (parent.range[0] !== current.range[0]) {
71
- return false;
72
- }
73
- current = parent;
74
- }
75
- }
76
40
  exports.default = (0, util_1.createRule)({
77
41
  name: 'no-unnecessary-type-assertion',
78
42
  meta: {
@@ -614,9 +578,9 @@ exports.default = (0, util_1.createRule)({
614
578
  // wrapped in parentheses to stay an expression.
615
579
  const firstOperandToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(closingAngleBracket), util_1.NullThrowsReasons.MissingToken('operand', 'type assertion'));
616
580
  const breaksExpressionStatement = ['{', 'function', 'class'].includes(firstOperandToken.value) &&
617
- isAtExpressionStatementStart(node);
581
+ (0, util_1.isStartOfExpressionStatement)(node);
618
582
  const breaksArrowFunctionBody = firstOperandToken.value === '{' &&
619
- isAtArrowFunctionBodyStart(node, context.sourceCode);
583
+ (0, util_1.isStartOfArrowFunctionBody)(node, context.sourceCode);
620
584
  const needsParens = breaksExpressionStatement || breaksArrowFunctionBody;
621
585
  const fixes = [];
622
586
  if (needsParens) {
@@ -220,7 +220,18 @@ exports.default = (0, util_1.createRule)({
220
220
  if (nextToken) {
221
221
  endAt = nextToken.range[0];
222
222
  }
223
- return fixer.removeRange([startAt, endAt]);
223
+ const awaitRemovalFix = fixer.removeRange([startAt, endAt]);
224
+ const firstOperandToken = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(awaitToken), util_1.NullThrowsReasons.MissingToken('operand', 'await expression'));
225
+ const shouldWrapInParentheses = (0, util_1.isOpeningBraceToken)(firstOperandToken) &&
226
+ (0, util_1.isStartOfArrowFunctionBody)(node, context.sourceCode);
227
+ if (shouldWrapInParentheses) {
228
+ return [
229
+ awaitRemovalFix,
230
+ fixer.insertTextBefore(node.argument, '('),
231
+ fixer.insertTextAfter(node.argument, ')'),
232
+ ];
233
+ }
234
+ return awaitRemovalFix;
224
235
  }
225
236
  function insertAwait(fixer, node, isHighPrecedence) {
226
237
  if (isHighPrecedence) {
@@ -14,7 +14,7 @@ exports.default = (0, util_1.createRule)({
14
14
  messages: {
15
15
  omittingRestParameter: '{{failureStringStart}} with a rest parameter.',
16
16
  omittingSingleParameter: '{{failureStringStart}} with an optional parameter.',
17
- singleParameterDifference: '{{failureStringStart}} taking `{{type1}} | {{type2}}`.',
17
+ singleParameterDifference: '{{failureStringStart}} taking `{{types}}`.',
18
18
  },
19
19
  schema: [
20
20
  {
@@ -57,20 +57,15 @@ exports.default = (0, util_1.createRule)({
57
57
  case 'single-parameter-difference': {
58
58
  const { p0, p1 } = unify;
59
59
  const lineOfOtherOverload = only2 ? undefined : p0.loc.start.line;
60
- const typeAnnotation0 = isTSParameterProperty(p0)
61
- ? p0.parameter.typeAnnotation
62
- : p0.typeAnnotation;
63
- const typeAnnotation1 = isTSParameterProperty(p1)
64
- ? p1.parameter.typeAnnotation
65
- : p1.typeAnnotation;
60
+ const typeAnnotation0 = getParameterTypeAnnotation(p0);
61
+ const typeAnnotation1 = getParameterTypeAnnotation(p1);
66
62
  context.report({
67
63
  loc: p1.loc,
68
64
  node: p1,
69
65
  messageId: 'singleParameterDifference',
70
66
  data: {
71
67
  failureStringStart: failureStringStart(lineOfOtherOverload),
72
- type1: context.sourceCode.getText(typeAnnotation0?.typeAnnotation),
73
- type2: context.sourceCode.getText(typeAnnotation1?.typeAnnotation),
68
+ types: getUnifiedTypeText(typeAnnotation0, typeAnnotation1),
74
69
  },
75
70
  });
76
71
  break;
@@ -114,7 +109,7 @@ exports.default = (0, util_1.createRule)({
114
109
  return undefined;
115
110
  }
116
111
  return a.params.length === b.params.length
117
- ? signaturesDifferBySingleParameter(a.params, b.params)
112
+ ? signaturesDifferBySingleParameter(a, b)
118
113
  : signaturesDifferByOptionalOrRestParameter(a, b);
119
114
  }
120
115
  function signaturesCanBeUnified(a, b, isTypeParameter) {
@@ -138,7 +133,7 @@ exports.default = (0, util_1.createRule)({
138
133
  return false;
139
134
  }
140
135
  }
141
- return (typesAreEqual(a.returnType, b.returnType) &&
136
+ return (typesAreEqual(a.returnType?.typeAnnotation, b.returnType?.typeAnnotation) &&
142
137
  // Must take the same type parameters.
143
138
  // If one uses a type parameter (from outside) and the other doesn't, they shouldn't be joined.
144
139
  (0, util_1.arraysAreEqual)(aTypeParams, bTypeParams, typeParametersAreEqual) &&
@@ -146,7 +141,9 @@ exports.default = (0, util_1.createRule)({
146
141
  signatureUsesTypeParameter(b, isTypeParameter));
147
142
  }
148
143
  /** Detect `a(x: number, y: number, z: number)` and `a(x: number, y: string, z: number)`. */
149
- function signaturesDifferBySingleParameter(types1, types2) {
144
+ function signaturesDifferBySingleParameter(signature0, signature1) {
145
+ const types1 = signature0.params;
146
+ const types2 = signature1.params;
150
147
  const firstParam1 = types1[0];
151
148
  const firstParam2 = types2[0];
152
149
  // exempt signatures with `this: void` from the rule
@@ -170,6 +167,39 @@ exports.default = (0, util_1.createRule)({
170
167
  ? { kind: 'single-parameter-difference', p0: a, p1: b }
171
168
  : undefined;
172
169
  }
170
+ function getParameterTypeAnnotation(parameter) {
171
+ return isTSParameterProperty(parameter)
172
+ ? parameter.parameter.typeAnnotation?.typeAnnotation
173
+ : parameter.typeAnnotation?.typeAnnotation;
174
+ }
175
+ function getUnifiedTypeText(type0, type1) {
176
+ // When a signature's parameter has no type annotation
177
+ if (type0 == null || type1 == null) {
178
+ return getUnionMemberText((0, util_1.nullThrows)(type0 ?? type1, 'Expected a type annotation for one of the parameters, but both were undefined'));
179
+ }
180
+ const members = [...getUnionMembers(type0), ...getUnionMembers(type1)];
181
+ const uniqueMembers = [];
182
+ for (const member of members) {
183
+ if (!uniqueMembers.some(other => typesAreEqual(other, member))) {
184
+ uniqueMembers.push(member);
185
+ }
186
+ }
187
+ return uniqueMembers
188
+ .map(member => getUnionMemberText(member))
189
+ .join(' | ');
190
+ }
191
+ function getUnionMembers(type) {
192
+ return type.type === utils_1.AST_NODE_TYPES.TSUnionType
193
+ ? type.types.flatMap(getUnionMembers)
194
+ : [type];
195
+ }
196
+ function getUnionMemberText(type) {
197
+ const text = context.sourceCode.getText(type);
198
+ const needsParentheses = type.type === utils_1.AST_NODE_TYPES.TSConditionalType ||
199
+ type.type === utils_1.AST_NODE_TYPES.TSConstructorType ||
200
+ type.type === utils_1.AST_NODE_TYPES.TSFunctionType;
201
+ return needsParentheses ? `(${text})` : text;
202
+ }
173
203
  function isThisParam(param) {
174
204
  return param?.type === utils_1.AST_NODE_TYPES.Identifier && param.name === 'this';
175
205
  }
@@ -209,15 +239,7 @@ exports.default = (0, util_1.createRule)({
209
239
  }
210
240
  }
211
241
  for (let i = 0; i < minLength; i++) {
212
- const sig1i = sig1[i];
213
- const sig2i = sig2[i];
214
- const typeAnnotation1 = isTSParameterProperty(sig1i)
215
- ? sig1i.parameter.typeAnnotation
216
- : sig1i.typeAnnotation;
217
- const typeAnnotation2 = isTSParameterProperty(sig2i)
218
- ? sig2i.parameter.typeAnnotation
219
- : sig2i.typeAnnotation;
220
- if (!typesAreEqual(typeAnnotation1, typeAnnotation2)) {
242
+ if (!typesAreEqual(getParameterTypeAnnotation(sig1[i]), getParameterTypeAnnotation(sig2[i]))) {
221
243
  return undefined;
222
244
  }
223
245
  }
@@ -265,14 +287,8 @@ exports.default = (0, util_1.createRule)({
265
287
  return node.type === utils_1.AST_NODE_TYPES.TSParameterProperty;
266
288
  }
267
289
  function parametersAreEqual(a, b) {
268
- const typeAnnotationA = isTSParameterProperty(a)
269
- ? a.parameter.typeAnnotation
270
- : a.typeAnnotation;
271
- const typeAnnotationB = isTSParameterProperty(b)
272
- ? b.parameter.typeAnnotation
273
- : b.typeAnnotation;
274
290
  return (parametersHaveEqualSigils(a, b) &&
275
- typesAreEqual(typeAnnotationA, typeAnnotationB));
291
+ typesAreEqual(getParameterTypeAnnotation(a), getParameterTypeAnnotation(b)));
276
292
  }
277
293
  /** True for optional/rest parameters. */
278
294
  function parameterMayBeMissing(p) {
@@ -300,8 +316,7 @@ exports.default = (0, util_1.createRule)({
300
316
  return (a === b ||
301
317
  (a != null &&
302
318
  b != null &&
303
- context.sourceCode.getText(a.typeAnnotation) ===
304
- context.sourceCode.getText(b.typeAnnotation)));
319
+ context.sourceCode.getText(a) === context.sourceCode.getText(b)));
305
320
  }
306
321
  function constraintsAreEqual(a, b) {
307
322
  return a === b || (a != null && a.type === b?.type);
@@ -18,6 +18,7 @@ export * from './isAssignee';
18
18
  export * from './isConditionalTest';
19
19
  export * from './isNodeEqual';
20
20
  export * from './isNullLiteral';
21
+ export * from './isStartOfArrowFunctionBody';
21
22
  export * from './isStartOfExpressionStatement';
22
23
  export * from './isUndefinedIdentifier';
23
24
  export * from './misc';
@@ -35,6 +35,7 @@ __exportStar(require("./isAssignee"), exports);
35
35
  __exportStar(require("./isConditionalTest"), exports);
36
36
  __exportStar(require("./isNodeEqual"), exports);
37
37
  __exportStar(require("./isNullLiteral"), exports);
38
+ __exportStar(require("./isStartOfArrowFunctionBody"), exports);
38
39
  __exportStar(require("./isStartOfExpressionStatement"), exports);
39
40
  __exportStar(require("./isUndefinedIdentifier"), exports);
40
41
  __exportStar(require("./misc"), 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;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isStartOfArrowFunctionBody = isStartOfArrowFunctionBody;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const astUtils_1 = require("./astUtils");
6
+ function isStartOfArrowFunctionBody(node, sourceCode) {
7
+ let current = node;
8
+ while (true) {
9
+ if ((0, astUtils_1.isParenthesized)(current, sourceCode)) {
10
+ return false;
11
+ }
12
+ const { parent } = current;
13
+ if (parent == null) {
14
+ return false;
15
+ }
16
+ if (parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
17
+ parent.body === current) {
18
+ return true;
19
+ }
20
+ if (parent.range[0] !== current.range[0]) {
21
+ return false;
22
+ }
23
+ current = parent;
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.67.1-alpha.3",
3
+ "version": "8.67.1-alpha.5",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -49,10 +49,10 @@
49
49
  "ignore": "^7.0.5",
50
50
  "natural-compare": "^1.4.0",
51
51
  "ts-api-utils": "^2.5.0",
52
- "@typescript-eslint/scope-manager": "8.67.1-alpha.3",
53
- "@typescript-eslint/type-utils": "8.67.1-alpha.3",
54
- "@typescript-eslint/utils": "8.67.1-alpha.3",
55
- "@typescript-eslint/visitor-keys": "8.67.1-alpha.3"
52
+ "@typescript-eslint/scope-manager": "8.67.1-alpha.5",
53
+ "@typescript-eslint/utils": "8.67.1-alpha.5",
54
+ "@typescript-eslint/type-utils": "8.67.1-alpha.5",
55
+ "@typescript-eslint/visitor-keys": "8.67.1-alpha.5"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/json-schema": "^7.0.15",
@@ -76,13 +76,13 @@
76
76
  "typescript": ">=4.8.4 <6.1.0",
77
77
  "unist-util-visit": "^5.0.0",
78
78
  "vitest": "^4.0.18",
79
- "@typescript-eslint/rule-schema-to-typescript-types": "8.67.1-alpha.3",
80
- "@typescript-eslint/rule-tester": "8.67.1-alpha.3"
79
+ "@typescript-eslint/rule-tester": "8.67.1-alpha.5",
80
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.67.1-alpha.5"
81
81
  },
82
82
  "peerDependencies": {
83
83
  "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
84
84
  "typescript": ">=4.8.4 <6.1.0",
85
- "@typescript-eslint/parser": "^8.67.1-alpha.3"
85
+ "@typescript-eslint/parser": "^8.67.1-alpha.5"
86
86
  },
87
87
  "funding": {
88
88
  "type": "opencollective",