@typescript-eslint/eslint-plugin 8.43.1-alpha.1 → 8.43.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.
@@ -1,5 +1,5 @@
1
1
  import type { TSESLint } from '@typescript-eslint/utils';
2
- export type MessageId = 'await' | 'awaitUsingOfNonAsyncDisposable' | 'convertToOrdinaryFor' | 'forAwaitOfNonAsyncIterable' | 'removeAwait';
2
+ export type MessageId = 'await' | 'awaitUsingOfNonAsyncDisposable' | 'convertToOrdinaryFor' | 'forAwaitOfNonAsyncIterable' | 'invalidPromiseAggregatorInput' | 'removeAwait';
3
3
  declare const _default: TSESLint.RuleModule<MessageId, [], import("../../rules").ESLintPluginDocs, TSESLint.RuleListener>;
4
4
  export default _default;
5
5
  //# sourceMappingURL=await-thenable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"await-thenable.d.ts","sourceRoot":"","sources":["../../src/rules/await-thenable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAiBnE,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,gCAAgC,GAChC,sBAAsB,GACtB,4BAA4B,GAC5B,aAAa,CAAC;;AAElB,wBAyJG"}
1
+ {"version":3,"file":"await-thenable.d.ts","sourceRoot":"","sources":["../../src/rules/await-thenable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAqBzD,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,gCAAgC,GAChC,sBAAsB,GACtB,4BAA4B,GAC5B,+BAA+B,GAC/B,aAAa,CAAC;;AAElB,wBA0MG"}
@@ -33,9 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ const utils_1 = require("@typescript-eslint/utils");
36
37
  const tsutils = __importStar(require("ts-api-utils"));
37
38
  const util_1 = require("../util");
38
39
  const getForStatementHeadLoc_1 = require("../util/getForStatementHeadLoc");
40
+ const isPromiseAggregatorMethod_1 = require("../util/isPromiseAggregatorMethod");
39
41
  exports.default = (0, util_1.createRule)({
40
42
  name: 'await-thenable',
41
43
  meta: {
@@ -51,6 +53,7 @@ exports.default = (0, util_1.createRule)({
51
53
  awaitUsingOfNonAsyncDisposable: 'Unexpected `await using` of a value that is not async disposable.',
52
54
  convertToOrdinaryFor: 'Convert to an ordinary `for...of` loop.',
53
55
  forAwaitOfNonAsyncIterable: 'Unexpected `for await...of` of a value that is not async iterable.',
56
+ invalidPromiseAggregatorInput: 'Unexpected iterable of non-Promise (non-"Thenable") values passed to promise aggregator.',
54
57
  removeAwait: 'Remove unnecessary `await`.',
55
58
  },
56
59
  schema: [],
@@ -81,6 +84,38 @@ exports.default = (0, util_1.createRule)({
81
84
  });
82
85
  }
83
86
  },
87
+ CallExpression(node) {
88
+ if (!(0, isPromiseAggregatorMethod_1.isPromiseAggregatorMethod)(context, services, node)) {
89
+ return;
90
+ }
91
+ const argument = node.arguments.at(0);
92
+ if (argument == null) {
93
+ return;
94
+ }
95
+ if (argument.type === utils_1.TSESTree.AST_NODE_TYPES.ArrayExpression) {
96
+ for (const element of argument.elements) {
97
+ if (element == null) {
98
+ continue;
99
+ }
100
+ const type = (0, util_1.getConstrainedTypeAtLocation)(services, element);
101
+ const tsNode = services.esTreeNodeToTSNodeMap.get(element);
102
+ if (containsNonAwaitableType(type, tsNode, checker)) {
103
+ context.report({
104
+ node: element,
105
+ messageId: 'invalidPromiseAggregatorInput',
106
+ });
107
+ }
108
+ }
109
+ return;
110
+ }
111
+ const type = (0, util_1.getConstrainedTypeAtLocation)(services, argument);
112
+ if (isInvalidPromiseAggregatorInput(checker, services.esTreeNodeToTSNodeMap.get(argument), type)) {
113
+ context.report({
114
+ node: argument,
115
+ messageId: 'invalidPromiseAggregatorInput',
116
+ });
117
+ }
118
+ },
84
119
  'ForOfStatement[await=true]'(node) {
85
120
  const type = services.getTypeAtLocation(node.right);
86
121
  if ((0, util_1.isTypeAnyType)(type)) {
@@ -144,3 +179,45 @@ exports.default = (0, util_1.createRule)({
144
179
  };
145
180
  },
146
181
  });
182
+ function isInvalidPromiseAggregatorInput(checker, node, type) {
183
+ // non array/tuple/iterable types already show up as a type error
184
+ if (!isIterable(type, checker)) {
185
+ return false;
186
+ }
187
+ for (const part of tsutils.unionConstituents(type)) {
188
+ const valueTypes = getValueTypesOfArrayLike(part, checker);
189
+ if (valueTypes != null) {
190
+ for (const typeArgument of valueTypes) {
191
+ if (containsNonAwaitableType(typeArgument, node, checker)) {
192
+ return true;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ return false;
198
+ }
199
+ function getValueTypesOfArrayLike(type, checker) {
200
+ if (checker.isTupleType(type)) {
201
+ return checker.getTypeArguments(type);
202
+ }
203
+ if (checker.isArrayLikeType(type)) {
204
+ return [
205
+ (0, util_1.nullThrows)(type.getNumberIndexType(), 'number index type should exist on an array-like'),
206
+ ];
207
+ }
208
+ // `Iterable<...>`
209
+ if (tsutils.isTypeReference(type)) {
210
+ return checker.getTypeArguments(type).slice(0, 1);
211
+ }
212
+ return null;
213
+ }
214
+ function containsNonAwaitableType(type, node, checker) {
215
+ return tsutils
216
+ .unionConstituents(type)
217
+ .some(typeArgumentPart => (0, util_1.needsToBeAwaited)(checker, node, typeArgumentPart) === util_1.Awaitable.Never);
218
+ }
219
+ function isIterable(type, checker) {
220
+ return tsutils
221
+ .unionConstituents(type)
222
+ .every(part => !!tsutils.getWellKnownSymbolPropertyOfType(part, 'iterator', checker));
223
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-string-starts-ends-with.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-string-starts-ends-with.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAqBnE,KAAK,4BAA4B,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,0BAA0B,CAAC,EAAE,4BAA4B,CAAC;KAC3D;CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;;AAE/D,wBAkrBG"}
1
+ {"version":3,"file":"prefer-string-starts-ends-with.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-string-starts-ends-with.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EAET,MAAM,0BAA0B,CAAC;AAqBlC,KAAK,4BAA4B,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,0BAA0B,CAAC,EAAE,4BAA4B,CAAC;KAC3D;CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;;AAE/D,wBA+qBG"}
@@ -260,9 +260,9 @@ exports.default = (0, util_1.createRule)({
260
260
  yield fixer.removeRange([callNode.range[1], node.range[1]]);
261
261
  }
262
262
  function getParent(node) {
263
- return (0, util_1.nullThrows)(node.parent?.type === utils_1.AST_NODE_TYPES.ChainExpression
263
+ return node.parent.type === utils_1.AST_NODE_TYPES.ChainExpression
264
264
  ? node.parent.parent
265
- : node.parent, util_1.NullThrowsReasons.MissingParent);
265
+ : node.parent;
266
266
  }
267
267
  return {
268
268
  // foo[0] === "a"
@@ -1 +1 @@
1
- {"version":3,"file":"explicitReturnTypeUtils.d.ts","sourceRoot":"","sources":["../../src/util/explicitReturnTypeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAWnE,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,CAAC,uBAAuB,GAChC,QAAQ,CAAC,kBAAkB,CAAC;AAChC,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,QAAQ,CAAC,mBAAmB,CAAC;AAE7E,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,YAAY;IAClD,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC;CACrC;AA6HD;;;;;;;;;;GAUG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,IAAI,EACJ,OAAO,GACR,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG,OAAO,CAetC;AAyBD,UAAU,OAAO;IACf,yCAAyC,CAAC,EAAE,OAAO,CAAC;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAeT;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAiCT;AAuBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC,EAC7C,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,cAAc,KAAK,IAAI,GAC7C,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,EACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,cAAc,KAAK,IAAI,GAC7C,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAyCjE"}
1
+ {"version":3,"file":"explicitReturnTypeUtils.d.ts","sourceRoot":"","sources":["../../src/util/explicitReturnTypeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAOnE,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,CAAC,uBAAuB,GAChC,QAAQ,CAAC,kBAAkB,CAAC;AAChC,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,QAAQ,CAAC,mBAAmB,CAAC;AAE7E,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,YAAY;IAClD,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC;CACrC;AA6HD;;;;;;;;;;GAUG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,IAAI,EACJ,OAAO,GACR,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG,OAAO,CAetC;AAyBD,UAAU,OAAO;IACf,yCAAyC,CAAC,EAAE,OAAO,CAAC;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAUT;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CA6BT;AAuBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC,EAC7C,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,cAAc,KAAK,IAAI,GAC7C,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,YAAY,CAAC,kBAAkB,CAAC,EACtC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,QAAQ,CAAC,UAAU,EAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,cAAc,KAAK,IAAI,GAC7C,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAyCjE"}
@@ -136,13 +136,12 @@ function isConstAssertion(node) {
136
136
  * True when the provided function expression is typed.
137
137
  */
138
138
  function isTypedFunctionExpression(node, options) {
139
- const parent = utils_1.ESLintUtils.nullThrows(node.parent, utils_1.ESLintUtils.NullThrowsReasons.MissingParent);
140
139
  if (!options.allowTypedFunctionExpressions) {
141
140
  return false;
142
141
  }
143
- return (isTypedParent(parent, node) ||
144
- isPropertyOfObjectWithType(parent) ||
145
- isConstructorArgument(parent));
142
+ return (isTypedParent(node.parent, node) ||
143
+ isPropertyOfObjectWithType(node.parent) ||
144
+ isConstructorArgument(node.parent));
146
145
  }
147
146
  /**
148
147
  * Check whether the function expression return type is either typed or valid
@@ -152,12 +151,11 @@ function isValidFunctionExpressionReturnType(node, options) {
152
151
  if (isTypedFunctionExpression(node, options)) {
153
152
  return true;
154
153
  }
155
- const parent = utils_1.ESLintUtils.nullThrows(node.parent, utils_1.ESLintUtils.NullThrowsReasons.MissingParent);
156
154
  if (options.allowExpressions &&
157
- parent.type !== utils_1.AST_NODE_TYPES.VariableDeclarator &&
158
- parent.type !== utils_1.AST_NODE_TYPES.MethodDefinition &&
159
- parent.type !== utils_1.AST_NODE_TYPES.ExportDefaultDeclaration &&
160
- parent.type !== utils_1.AST_NODE_TYPES.PropertyDefinition) {
155
+ node.parent.type !== utils_1.AST_NODE_TYPES.VariableDeclarator &&
156
+ node.parent.type !== utils_1.AST_NODE_TYPES.MethodDefinition &&
157
+ node.parent.type !== utils_1.AST_NODE_TYPES.ExportDefaultDeclaration &&
158
+ node.parent.type !== utils_1.AST_NODE_TYPES.PropertyDefinition) {
161
159
  return true;
162
160
  }
163
161
  // https://github.com/typescript-eslint/typescript-eslint/issues/653
@@ -0,0 +1,4 @@
1
+ import type { ParserServicesWithTypeInformation, TSESTree } from '@typescript-eslint/utils';
2
+ import type { RuleContext } from '@typescript-eslint/utils/ts-eslint';
3
+ export declare function isPromiseAggregatorMethod(context: RuleContext<string, unknown[]>, services: ParserServicesWithTypeInformation, node: TSESTree.CallExpression): boolean;
4
+ //# sourceMappingURL=isPromiseAggregatorMethod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isPromiseAggregatorMethod.d.ts","sourceRoot":"","sources":["../../src/util/isPromiseAggregatorMethod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iCAAiC,EACjC,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAiBtE,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EACvC,QAAQ,EAAE,iCAAiC,EAC3C,IAAI,EAAE,QAAQ,CAAC,cAAc,GAC5B,OAAO,CAeT"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPromiseAggregatorMethod = isPromiseAggregatorMethod;
4
+ const type_utils_1 = require("@typescript-eslint/type-utils");
5
+ const utils_1 = require("@typescript-eslint/utils");
6
+ const misc_1 = require("./misc");
7
+ const PROMISE_CONSTRUCTOR_ARRAY_METHODS = new Set([
8
+ 'all',
9
+ 'allSettled',
10
+ 'race',
11
+ 'any',
12
+ ]);
13
+ function isPromiseAggregatorMethod(context, services, node) {
14
+ if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
15
+ return false;
16
+ }
17
+ const staticAccessValue = (0, misc_1.getStaticMemberAccessValue)(node.callee, context);
18
+ if (!PROMISE_CONSTRUCTOR_ARRAY_METHODS.has(staticAccessValue)) {
19
+ return false;
20
+ }
21
+ return (0, type_utils_1.isPromiseConstructorLike)(services.program, (0, type_utils_1.getConstrainedTypeAtLocation)(services, node.callee.object));
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.43.1-alpha.1",
3
+ "version": "8.43.1-alpha.3",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -59,10 +59,10 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@eslint-community/regexpp": "^4.10.0",
62
- "@typescript-eslint/scope-manager": "8.43.1-alpha.1",
63
- "@typescript-eslint/type-utils": "8.43.1-alpha.1",
64
- "@typescript-eslint/utils": "8.43.1-alpha.1",
65
- "@typescript-eslint/visitor-keys": "8.43.1-alpha.1",
62
+ "@typescript-eslint/scope-manager": "8.43.1-alpha.3",
63
+ "@typescript-eslint/type-utils": "8.43.1-alpha.3",
64
+ "@typescript-eslint/utils": "8.43.1-alpha.3",
65
+ "@typescript-eslint/visitor-keys": "8.43.1-alpha.3",
66
66
  "graphemer": "^1.4.0",
67
67
  "ignore": "^7.0.0",
68
68
  "natural-compare": "^1.4.0",
@@ -71,8 +71,8 @@
71
71
  "devDependencies": {
72
72
  "@types/mdast": "^4.0.3",
73
73
  "@types/natural-compare": "*",
74
- "@typescript-eslint/rule-schema-to-typescript-types": "8.43.1-alpha.1",
75
- "@typescript-eslint/rule-tester": "8.43.1-alpha.1",
74
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.43.1-alpha.3",
75
+ "@typescript-eslint/rule-tester": "8.43.1-alpha.3",
76
76
  "@vitest/coverage-v8": "^3.1.3",
77
77
  "ajv": "^6.12.6",
78
78
  "cross-fetch": "*",
@@ -92,7 +92,7 @@
92
92
  "vitest": "^3.1.3"
93
93
  },
94
94
  "peerDependencies": {
95
- "@typescript-eslint/parser": "^8.43.1-alpha.1",
95
+ "@typescript-eslint/parser": "^8.43.1-alpha.3",
96
96
  "eslint": "^8.57.0 || ^9.0.0",
97
97
  "typescript": ">=4.8.4 <6.0.0"
98
98
  },