@typescript-eslint/eslint-plugin 8.25.1-alpha.1 → 8.25.1-alpha.11

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 +1 @@
1
- {"version":3,"file":"no-invalid-void-type.d.ts","sourceRoot":"","sources":["../../src/rules/no-invalid-void-type.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,OAAO;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,2BAA2B,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,UAAU,GAClB,uBAAuB,GACvB,sBAAsB,GACtB,+BAA+B,GAC/B,iCAAiC,GACjC,0CAA0C,GAC1C,6BAA6B,CAAC;;AAElC,wBA0OG"}
1
+ {"version":3,"file":"no-invalid-void-type.d.ts","sourceRoot":"","sources":["../../src/rules/no-invalid-void-type.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,OAAO;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,2BAA2B,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,UAAU,GAClB,uBAAuB,GACvB,sBAAsB,GACtB,+BAA+B,GAC/B,iCAAiC,GACjC,0CAA0C,GAC1C,6BAA6B,CAAC;;AAElC,wBA2OG"}
@@ -57,6 +57,7 @@ exports.default = (0, util_1.createRule)({
57
57
  utils_1.AST_NODE_TYPES.TSPropertySignature,
58
58
  utils_1.AST_NODE_TYPES.CallExpression,
59
59
  utils_1.AST_NODE_TYPES.PropertyDefinition,
60
+ utils_1.AST_NODE_TYPES.AccessorProperty,
60
61
  utils_1.AST_NODE_TYPES.Identifier,
61
62
  ];
62
63
  const validUnionMembers = [
@@ -185,7 +185,12 @@ function isTypeParameterRepeatedInAST(node, references, startOfBody = Infinity)
185
185
  if (reference.identifier.parent.type === utils_1.AST_NODE_TYPES.TSTypeReference) {
186
186
  const grandparent = skipConstituentsUpward(reference.identifier.parent.parent);
187
187
  if (grandparent.type === utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation &&
188
- grandparent.params.includes(reference.identifier.parent)) {
188
+ grandparent.params.includes(reference.identifier.parent) &&
189
+ // Array and ReadonlyArray must be handled carefully
190
+ // let's defer the check to the type-aware phase
191
+ !(grandparent.parent.type === utils_1.AST_NODE_TYPES.TSTypeReference &&
192
+ grandparent.parent.typeName.type === utils_1.AST_NODE_TYPES.Identifier &&
193
+ ['Array', 'ReadonlyArray'].includes(grandparent.parent.typeName.name))) {
189
194
  return true;
190
195
  }
191
196
  }
@@ -215,14 +220,14 @@ function countTypeParameterUsage(checker, node) {
215
220
  const counts = new Map();
216
221
  if (ts.isClassLike(node)) {
217
222
  for (const typeParameter of node.typeParameters) {
218
- collectTypeParameterUsageCounts(checker, typeParameter, counts);
223
+ collectTypeParameterUsageCounts(checker, typeParameter, counts, true);
219
224
  }
220
225
  for (const member of node.members) {
221
- collectTypeParameterUsageCounts(checker, member, counts);
226
+ collectTypeParameterUsageCounts(checker, member, counts, true);
222
227
  }
223
228
  }
224
229
  else {
225
- collectTypeParameterUsageCounts(checker, node, counts);
230
+ collectTypeParameterUsageCounts(checker, node, counts, false);
226
231
  }
227
232
  return counts;
228
233
  }
@@ -231,7 +236,7 @@ function countTypeParameterUsage(checker, node) {
231
236
  * appears in the given type by checking its uses through its type references.
232
237
  * This is essentially a limited subset of the scope manager, but for types.
233
238
  */
234
- function collectTypeParameterUsageCounts(checker, node, foundIdentifierUsages) {
239
+ function collectTypeParameterUsageCounts(checker, node, foundIdentifierUsages, fromClass) {
235
240
  const visitedSymbolLists = new Set();
236
241
  const type = checker.getTypeAtLocation(node);
237
242
  const typeUsages = new Map();
@@ -246,7 +251,7 @@ function collectTypeParameterUsageCounts(checker, node, foundIdentifierUsages) {
246
251
  if (!functionLikeType) {
247
252
  visitType(type, false);
248
253
  }
249
- function visitType(type, assumeMultipleUses) {
254
+ function visitType(type, assumeMultipleUses, isReturnType = false) {
250
255
  // Seeing the same type > (threshold=3 ** 2) times indicates a likely
251
256
  // recursive type, like `type T = { [P in keyof T]: T }`.
252
257
  // If it's not recursive, then heck, we've seen it enough times that any
@@ -288,9 +293,21 @@ function collectTypeParameterUsageCounts(checker, node, foundIdentifierUsages) {
288
293
  }
289
294
  // Tuple types like `[K, V]`
290
295
  // Generic type references like `Map<K, V>`
291
- else if (tsutils.isTupleType(type) || tsutils.isTypeReference(type)) {
296
+ else if (tsutils.isTypeReference(type)) {
292
297
  for (const typeArgument of type.typeArguments ?? []) {
293
- visitType(typeArgument, true);
298
+ // currently, if we are in a "class context", everything is accepted
299
+ let thisAssumeMultipleUses = fromClass || assumeMultipleUses;
300
+ // special cases - readonly arrays/tuples are considered only to use the
301
+ // type parameter once. Mutable arrays/tuples are considered to use the
302
+ // type parameter multiple times if and only if they are returned.
303
+ // other kind of type references always count as multiple uses
304
+ thisAssumeMultipleUses ||= tsutils.isTupleType(type.target)
305
+ ? isReturnType && !type.target.readonly
306
+ : checker.isArrayType(type.target)
307
+ ? isReturnType &&
308
+ type.symbol?.getName() === 'Array'
309
+ : true;
310
+ visitType(typeArgument, thisAssumeMultipleUses, isReturnType);
294
311
  }
295
312
  }
296
313
  // Template literals like `a${T}b`
@@ -359,7 +376,7 @@ function collectTypeParameterUsageCounts(checker, node, foundIdentifierUsages) {
359
376
  visitType(typeParameter, false);
360
377
  }
361
378
  visitType(checker.getTypePredicateOfSignature(signature)?.type ??
362
- signature.getReturnType(), false);
379
+ signature.getReturnType(), false, true);
363
380
  }
364
381
  function visitSymbolsListOnce(symbols, assumeMultipleUses) {
365
382
  if (visitedSymbolLists.has(symbols)) {
@@ -383,7 +383,13 @@ function getOverloadInfo(node) {
383
383
  return '()';
384
384
  default: {
385
385
  const { key } = node;
386
- return isIdentifier(key) ? key.name : key.raw;
386
+ if (isPrivateIdentifier(key)) {
387
+ return `private_identifier_${key.name}`;
388
+ }
389
+ if (isIdentifier(key)) {
390
+ return `identifier_${key.name}`;
391
+ }
392
+ return key.raw;
387
393
  }
388
394
  }
389
395
  }
@@ -400,6 +406,9 @@ function getStaticParameterName(param) {
400
406
  function isIdentifier(node) {
401
407
  return node.type === utils_1.AST_NODE_TYPES.Identifier;
402
408
  }
409
+ function isPrivateIdentifier(node) {
410
+ return node.type === utils_1.AST_NODE_TYPES.PrivateIdentifier;
411
+ }
403
412
  function isGetterOrSetter(node) {
404
413
  return node.kind === 'get' || node.kind === 'set';
405
414
  }
@@ -82,10 +82,30 @@ For example, the following `T` is used multiple times by virtue of being in an `
82
82
  declare function createStateHistory<T>(): T[];
83
83
  ```
84
84
 
85
- This is because the type parameter `T` relates multiple methods in the `T[]` together, making it used more than once.
85
+ This is because the type parameter `T` relates multiple methods in `T[]` (`Array<T>`) together, making it used more than once.
86
86
 
87
87
  Therefore, this rule won't report on type parameters used as a type argument.
88
- That includes type arguments given to global types such as `Array` (including the `T[]` shorthand and in tuples), `Map`, and `Set`.
88
+ This includes type arguments provided to global types such as `Array`, `Map`, and `Set` that have multiple methods and properties that can change values based on the type parameter.
89
+
90
+ On the other hand, readonly and fixed array-likes such as `readonly T[]`, `ReadonlyArray`, and tuples such as `[T]` are special cases that are specifically reported on when used as input types, or as `readonly` output types.
91
+ The following example will be reported because `T` is used only once as type argument for the `ReadonlyArray` global type:
92
+
93
+ <Tabs>
94
+ <TabItem value="❌ Incorrect">
95
+
96
+ ```ts
97
+ declare function length<T>(array: ReadonlyArray<T>): number;
98
+ ```
99
+
100
+ </TabItem>
101
+ <TabItem value="✅ Correct">
102
+
103
+ ```ts
104
+ declare function length(array: ReadonlyArray<unknown>): number;
105
+ ```
106
+
107
+ </TabItem>
108
+ </Tabs>
89
109
 
90
110
  ## FAQ
91
111
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.25.1-alpha.1",
3
+ "version": "8.25.1-alpha.11",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -56,16 +56,16 @@
56
56
  "generate:breaking-changes": "tsx tools/generate-breaking-changes.mts",
57
57
  "generate:configs": "npx nx generate-configs repo",
58
58
  "lint": "npx nx lint",
59
- "test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --logHeapUsage",
59
+ "test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --logHeapUsage",
60
60
  "test-single": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --no-coverage",
61
61
  "check-types": "npx nx typecheck"
62
62
  },
63
63
  "dependencies": {
64
64
  "@eslint-community/regexpp": "^4.10.0",
65
- "@typescript-eslint/scope-manager": "8.25.1-alpha.1",
66
- "@typescript-eslint/type-utils": "8.25.1-alpha.1",
67
- "@typescript-eslint/utils": "8.25.1-alpha.1",
68
- "@typescript-eslint/visitor-keys": "8.25.1-alpha.1",
65
+ "@typescript-eslint/scope-manager": "8.25.1-alpha.11",
66
+ "@typescript-eslint/type-utils": "8.25.1-alpha.11",
67
+ "@typescript-eslint/utils": "8.25.1-alpha.11",
68
+ "@typescript-eslint/visitor-keys": "8.25.1-alpha.11",
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.25.1-alpha.1",
80
- "@typescript-eslint/rule-tester": "8.25.1-alpha.1",
79
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.25.1-alpha.11",
80
+ "@typescript-eslint/rule-tester": "8.25.1-alpha.11",
81
81
  "ajv": "^6.12.6",
82
82
  "cross-env": "^7.0.3",
83
83
  "cross-fetch": "*",