eslint-plugin-ts-data-forge 0.8.0 → 0.8.2

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.
Files changed (95) hide show
  1. package/dist/rules/ast-utils.d.mts.map +1 -1
  2. package/dist/rules/ast-utils.mjs +24 -24
  3. package/dist/rules/ast-utils.mjs.map +1 -1
  4. package/dist/rules/branded-number-types.mjs.map +1 -1
  5. package/dist/rules/import-utils.d.mts.map +1 -1
  6. package/dist/rules/import-utils.mjs +4 -2
  7. package/dist/rules/import-utils.mjs.map +1 -1
  8. package/dist/rules/no-unnecessary-type-guard.d.mts.map +1 -1
  9. package/dist/rules/no-unnecessary-type-guard.mjs +37 -23
  10. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  11. package/dist/rules/prefer-arr-is-array.d.mts.map +1 -1
  12. package/dist/rules/prefer-arr-is-array.mjs +14 -7
  13. package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
  14. package/dist/rules/prefer-arr-is-bounded-length-array.d.mts.map +1 -1
  15. package/dist/rules/prefer-arr-is-bounded-length-array.mjs +8 -4
  16. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  17. package/dist/rules/prefer-arr-is-fixed-length-array.d.mts.map +1 -1
  18. package/dist/rules/prefer-arr-is-fixed-length-array.mjs +8 -4
  19. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  20. package/dist/rules/prefer-arr-is-max-length-array.d.mts.map +1 -1
  21. package/dist/rules/prefer-arr-is-max-length-array.mjs +10 -5
  22. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  23. package/dist/rules/prefer-arr-is-min-length-array.d.mts.map +1 -1
  24. package/dist/rules/prefer-arr-is-min-length-array.mjs +10 -5
  25. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  26. package/dist/rules/prefer-arr-is-non-empty.d.mts.map +1 -1
  27. package/dist/rules/prefer-arr-is-non-empty.mjs +4 -2
  28. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  29. package/dist/rules/prefer-arr-scan.d.mts.map +1 -1
  30. package/dist/rules/prefer-arr-scan.mjs +35 -18
  31. package/dist/rules/prefer-arr-scan.mjs.map +1 -1
  32. package/dist/rules/prefer-arr-sum.d.mts.map +1 -1
  33. package/dist/rules/prefer-arr-sum.mjs +6 -3
  34. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  35. package/dist/rules/prefer-arr-uniq.d.mts.map +1 -1
  36. package/dist/rules/prefer-arr-uniq.mjs +30 -24
  37. package/dist/rules/prefer-arr-uniq.mjs.map +1 -1
  38. package/dist/rules/prefer-as-int.d.mts.map +1 -1
  39. package/dist/rules/prefer-as-int.mjs +11 -14
  40. package/dist/rules/prefer-as-int.mjs.map +1 -1
  41. package/dist/rules/prefer-canonical-array-slicing.d.mts.map +1 -1
  42. package/dist/rules/prefer-canonical-array-slicing.mjs +32 -16
  43. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  44. package/dist/rules/prefer-canonical-length-cast.d.mts.map +1 -1
  45. package/dist/rules/prefer-canonical-length-cast.mjs +11 -7
  46. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  47. package/dist/rules/prefer-canonical-length-guard.d.mts.map +1 -1
  48. package/dist/rules/prefer-canonical-length-guard.mjs +8 -4
  49. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  50. package/dist/rules/prefer-comparison-over-nullish-guard.d.mts.map +1 -1
  51. package/dist/rules/prefer-comparison-over-nullish-guard.mjs +6 -3
  52. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  53. package/dist/rules/prefer-is-non-null-object.d.mts.map +1 -1
  54. package/dist/rules/prefer-is-non-null-object.mjs +29 -31
  55. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  56. package/dist/rules/prefer-is-record-and-has-key.d.mts.map +1 -1
  57. package/dist/rules/prefer-is-record-and-has-key.mjs +10 -5
  58. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  59. package/dist/rules/prefer-num-safe-parse-float.d.mts.map +1 -1
  60. package/dist/rules/prefer-num-safe-parse-float.mjs +12 -6
  61. package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
  62. package/dist/rules/prefer-num-safe-parse-int.d.mts.map +1 -1
  63. package/dist/rules/prefer-num-safe-parse-int.mjs +12 -6
  64. package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
  65. package/dist/rules/prefer-obj-over-entries-round-trip.d.mts.map +1 -1
  66. package/dist/rules/prefer-obj-over-entries-round-trip.mjs +22 -11
  67. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  68. package/dist/rules/prefer-range-for-loop.d.mts.map +1 -1
  69. package/dist/rules/prefer-range-for-loop.mjs +2 -1
  70. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  71. package/package.json +25 -24
  72. package/src/rules/ast-utils.mts +38 -26
  73. package/src/rules/branded-number-types.mts +1 -1
  74. package/src/rules/import-utils.mts +6 -2
  75. package/src/rules/no-unnecessary-type-guard.mts +56 -23
  76. package/src/rules/prefer-arr-is-array.mts +21 -7
  77. package/src/rules/prefer-arr-is-bounded-length-array.mts +12 -4
  78. package/src/rules/prefer-arr-is-fixed-length-array.mts +12 -4
  79. package/src/rules/prefer-arr-is-max-length-array.mts +15 -5
  80. package/src/rules/prefer-arr-is-min-length-array.mts +15 -5
  81. package/src/rules/prefer-arr-is-non-empty.mts +6 -2
  82. package/src/rules/prefer-arr-scan.mts +52 -18
  83. package/src/rules/prefer-arr-sum.mts +9 -3
  84. package/src/rules/prefer-arr-uniq.mts +42 -26
  85. package/src/rules/prefer-as-int.mts +17 -25
  86. package/src/rules/prefer-canonical-array-slicing.mts +48 -16
  87. package/src/rules/prefer-canonical-length-cast.mts +15 -7
  88. package/src/rules/prefer-canonical-length-guard.mts +12 -4
  89. package/src/rules/prefer-comparison-over-nullish-guard.mts +9 -3
  90. package/src/rules/prefer-is-non-null-object.mts +35 -31
  91. package/src/rules/prefer-is-record-and-has-key.mts +15 -5
  92. package/src/rules/prefer-num-safe-parse-float.mts +17 -6
  93. package/src/rules/prefer-num-safe-parse-int.mts +18 -6
  94. package/src/rules/prefer-obj-over-entries-round-trip.mts +33 -11
  95. package/src/rules/prefer-range-for-loop.mts +3 -1
@@ -156,7 +156,9 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
156
156
  const strictNullChecks =
157
157
  compilerOptions.strictNullChecks ?? compilerOptions.strict ?? false;
158
158
 
159
- if (!strictNullChecks) return {};
159
+ if (!strictNullChecks) {
160
+ return {};
161
+ }
160
162
 
161
163
  const checker = parserServices.program.getTypeChecker();
162
164
 
@@ -249,7 +251,9 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
249
251
 
250
252
  return {
251
253
  CallExpression: (node) => {
252
- if (node.arguments.length !== 1) return;
254
+ if (node.arguments.length !== 1) {
255
+ return;
256
+ }
253
257
 
254
258
  const argument = node.arguments[0];
255
259
 
@@ -262,15 +266,21 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
262
266
 
263
267
  const resolved = resolveGuard(node.callee);
264
268
 
265
- if (resolved === undefined) return;
269
+ if (resolved === undefined) {
270
+ return;
271
+ }
266
272
 
267
273
  const { canonicalName, propertyNode, isNamespace } = resolved;
268
274
 
269
- if (ignored.has(canonicalName)) return;
275
+ if (ignored.has(canonicalName)) {
276
+ return;
277
+ }
270
278
 
271
279
  const spec = GUARD_SPECS[canonicalName];
272
280
 
273
- if (spec === undefined) return;
281
+ if (spec === undefined) {
282
+ return;
283
+ }
274
284
 
275
285
  const argTsNode = parserServices.esTreeNodeToTSNodeMap.get(argument);
276
286
 
@@ -278,7 +288,9 @@ export const noUnnecessaryTypeGuard: TSESLint.RuleModule<MessageIds, Options> =
278
288
 
279
289
  const parts = collectUnionParts(argType);
280
290
 
281
- if (parts === undefined) return; // opaque / generic → bail conservatively
291
+ if (parts === undefined) {
292
+ return; // opaque / generic → bail conservatively
293
+ }
282
294
 
283
295
  const inputAtoms = new Set(parts.map(classifyAtom));
284
296
 
@@ -413,7 +425,9 @@ const collectUnionParts = (type: ts.Type): readonly ts.Type[] | undefined => {
413
425
  const parts = type.isUnion() ? type.types : ([type] as const);
414
426
 
415
427
  for (const part of parts) {
416
- if ((part.flags & DEFERRED_OR_OPAQUE_FLAGS) !== 0) return undefined;
428
+ if ((part.flags & DEFERRED_OR_OPAQUE_FLAGS) !== 0) {
429
+ return undefined;
430
+ }
417
431
  }
418
432
 
419
433
  return parts;
@@ -473,19 +487,33 @@ const isCallableType = (
473
487
  const classifyAtom = (type: ts.Type): Atom => {
474
488
  const { flags } = type;
475
489
 
476
- if ((flags & ts.TypeFlags.Undefined) !== 0) return 'undefined';
490
+ if ((flags & ts.TypeFlags.Undefined) !== 0) {
491
+ return 'undefined';
492
+ }
477
493
 
478
- if ((flags & ts.TypeFlags.Null) !== 0) return 'null';
494
+ if ((flags & ts.TypeFlags.Null) !== 0) {
495
+ return 'null';
496
+ }
479
497
 
480
- if ((flags & ts.TypeFlags.BooleanLike) !== 0) return 'boolean';
498
+ if ((flags & ts.TypeFlags.BooleanLike) !== 0) {
499
+ return 'boolean';
500
+ }
481
501
 
482
- if ((flags & ts.TypeFlags.NumberLike) !== 0) return 'number';
502
+ if ((flags & ts.TypeFlags.NumberLike) !== 0) {
503
+ return 'number';
504
+ }
483
505
 
484
- if ((flags & ts.TypeFlags.StringLike) !== 0) return 'string';
506
+ if ((flags & ts.TypeFlags.StringLike) !== 0) {
507
+ return 'string';
508
+ }
485
509
 
486
- if ((flags & ts.TypeFlags.BigIntLike) !== 0) return 'bigint';
510
+ if ((flags & ts.TypeFlags.BigIntLike) !== 0) {
511
+ return 'bigint';
512
+ }
487
513
 
488
- if ((flags & ts.TypeFlags.ESSymbolLike) !== 0) return 'symbol';
514
+ if ((flags & ts.TypeFlags.ESSymbolLike) !== 0) {
515
+ return 'symbol';
516
+ }
489
517
 
490
518
  // Branded primitives (e.g. `NonEmptyString = string & {...}`) are
491
519
  // intersections; classify them by their underlying primitive constituent.
@@ -493,7 +521,9 @@ const classifyAtom = (type: ts.Type): Atom => {
493
521
  for (const constituent of type.types) {
494
522
  const atom = classifyAtom(constituent);
495
523
 
496
- if (atom !== 'other') return atom;
524
+ if (atom !== 'other') {
525
+ return atom;
526
+ }
497
527
  }
498
528
  }
499
529
 
@@ -525,13 +555,19 @@ const isGuaranteedNonEmptyString = (
525
555
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
526
556
  checker: ts.TypeChecker,
527
557
  ): boolean => {
528
- if (type.isStringLiteral()) return type.value !== '';
558
+ if (type.isStringLiteral()) {
559
+ return type.value !== '';
560
+ }
529
561
 
530
- if (type.getProperty(BRAND_MARKER_PROPERTY) === undefined) return false;
562
+ if (type.getProperty(BRAND_MARKER_PROPERTY) === undefined) {
563
+ return false;
564
+ }
531
565
 
532
566
  const minLengthSymbol = type.getProperty(MIN_LENGTH_BRAND_KEY);
533
567
 
534
- if (minLengthSymbol === undefined) return false;
568
+ if (minLengthSymbol === undefined) {
569
+ return false;
570
+ }
535
571
 
536
572
  // The `MinLength` brand value is `MinLengthTuple<N, 0>`; it has a required
537
573
  // first element (`'0'`) exactly when `N >= 1`, i.e. the string is non-empty.
@@ -547,11 +583,8 @@ const isGuaranteedNonEmptyString = (
547
583
  * literal and non-string types cannot.
548
584
  */
549
585
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
550
- const couldBeNonEmptyString = (type: ts.Type): boolean => {
551
- if (type.isStringLiteral()) return type.value !== '';
552
-
553
- return classifyAtom(type) === 'string';
554
- };
586
+ const couldBeNonEmptyString = (type: ts.Type): boolean =>
587
+ type.isStringLiteral() ? type.value !== '' : classifyAtom(type) === 'string';
555
588
 
556
589
  /**
557
590
  * Returns `true` when evaluating the expression cannot have observable side
@@ -40,7 +40,9 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
40
40
 
41
41
  return {
42
42
  CallExpression: (node) => {
43
- if (!isArrayIsArrayCall(node)) return;
43
+ if (!isArrayIsArrayCall(node)) {
44
+ return;
45
+ }
44
46
 
45
47
  mut_nodesToFix.push(node);
46
48
  },
@@ -59,7 +61,9 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
59
61
  fix: (fixer) => {
60
62
  const callee = node.callee;
61
63
 
62
- if (callee.type !== AST_NODE_TYPES.MemberExpression) return [];
64
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) {
65
+ return [];
66
+ }
63
67
 
64
68
  const replacement = `Arr.isArray${sourceCode.getText(node).slice(sourceCode.getText(callee).length)}`;
65
69
 
@@ -82,17 +86,27 @@ export const preferArrIsArray: TSESLint.RuleModule<MessageIds, Options> = {
82
86
  const isArrayIsArrayCall = (
83
87
  node: DeepReadonly<TSESTree.CallExpression>,
84
88
  ): boolean => {
85
- if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
89
+ if (node.callee.type !== AST_NODE_TYPES.MemberExpression) {
90
+ return false;
91
+ }
86
92
 
87
93
  const { object, property } = node.callee;
88
94
 
89
- if (object.type !== AST_NODE_TYPES.Identifier) return false;
95
+ if (object.type !== AST_NODE_TYPES.Identifier) {
96
+ return false;
97
+ }
90
98
 
91
- if (object.name !== 'Array') return false;
99
+ if (object.name !== 'Array') {
100
+ return false;
101
+ }
92
102
 
93
- if (property.type !== AST_NODE_TYPES.Identifier) return false;
103
+ if (property.type !== AST_NODE_TYPES.Identifier) {
104
+ return false;
105
+ }
94
106
 
95
- if (property.name !== 'isArray') return false;
107
+ if (property.name !== 'isArray') {
108
+ return false;
109
+ }
96
110
 
97
111
  return true;
98
112
  };
@@ -47,16 +47,22 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
47
47
  return {
48
48
  LogicalExpression: (node) => {
49
49
  // Only `a && b` can encode a `min && max` length range.
50
- if (node.operator !== '&&') return;
50
+ if (node.operator !== '&&') {
51
+ return;
52
+ }
51
53
 
52
54
  const left = parseLengthComparison(node.left, sourceCode);
53
55
 
54
56
  const right = parseLengthComparison(node.right, sourceCode);
55
57
 
56
- if (left === undefined || right === undefined) return;
58
+ if (left === undefined || right === undefined) {
59
+ return;
60
+ }
57
61
 
58
62
  // Need one lower bound and one upper bound on the same array.
59
- if (left.kind === right.kind) return;
63
+ if (left.kind === right.kind) {
64
+ return;
65
+ }
60
66
 
61
67
  if (
62
68
  sourceCode.getText(left.array) !== sourceCode.getText(right.array)
@@ -83,7 +89,9 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
83
89
  const isArrayType =
84
90
  checker.isArrayType(type) || checker.isTupleType(type);
85
91
 
86
- if (!isArrayType) return;
92
+ if (!isArrayType) {
93
+ return;
94
+ }
87
95
  } else {
88
96
  return;
89
97
  }
@@ -52,7 +52,9 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
52
52
  return {
53
53
  BinaryExpression: (node) => {
54
54
  // Check for `xs.length === n` or `n === xs.length` or `xs.length !== n`
55
- if (node.operator !== '===' && node.operator !== '!==') return;
55
+ if (node.operator !== '===' && node.operator !== '!==') {
56
+ return;
57
+ }
56
58
 
57
59
  const isNegated = node.operator === '!==';
58
60
 
@@ -62,10 +64,14 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
62
64
 
63
65
  const valueSide = node[isLengthOnLeft ? 'right' : 'left'];
64
66
 
65
- if (!isLengthAccess(lengthSide)) return;
67
+ if (!isLengthAccess(lengthSide)) {
68
+ return;
69
+ }
66
70
 
67
71
  // Only match integer literals or const variables initialized with integer literals
68
- if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) return;
72
+ if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) {
73
+ return;
74
+ }
69
75
 
70
76
  // lengthSide is MemberExpression accessing .length
71
77
  const arrayExpression = lengthSide.object;
@@ -83,7 +89,9 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
83
89
  const isArrayType =
84
90
  checker.isArrayType(type) || checker.isTupleType(type);
85
91
 
86
- if (!isArrayType) return;
92
+ if (!isArrayType) {
93
+ return;
94
+ }
87
95
  } else {
88
96
  return;
89
97
  }
@@ -50,11 +50,15 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
50
50
  return {
51
51
  BinaryExpression: (node) => {
52
52
  // Check for `xs.length <= n` or `n >= xs.length`
53
- if (node.operator !== '>=' && node.operator !== '<=') return;
53
+ if (node.operator !== '>=' && node.operator !== '<=') {
54
+ return;
55
+ }
54
56
 
55
57
  // Defer to `prefer-arr-is-bounded-length-array` when this comparison is
56
58
  // the upper bound of a `min && max` pair on the same array.
57
- if (isPartOfBoundedLengthCheck(node, sourceCode)) return;
59
+ if (isPartOfBoundedLengthCheck(node, sourceCode)) {
60
+ return;
61
+ }
58
62
 
59
63
  // xs.length <= n or n >= xs.length
60
64
  const isLengthOnLeft = node.operator === '<=';
@@ -64,10 +68,14 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
64
68
  const valueSide = node[isLengthOnLeft ? 'right' : 'left'];
65
69
 
66
70
  // Check if lengthSide is accessing .length
67
- if (!isLengthAccess(lengthSide)) return;
71
+ if (!isLengthAccess(lengthSide)) {
72
+ return;
73
+ }
68
74
 
69
75
  // Only match integer literals or const variables initialized with integer literals
70
- if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) return;
76
+ if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) {
77
+ return;
78
+ }
71
79
 
72
80
  // lengthSide is MemberExpression accessing .length
73
81
  const arrayExpression = lengthSide.object;
@@ -85,7 +93,9 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
85
93
  const isArrayType =
86
94
  checker.isArrayType(type) || checker.isTupleType(type);
87
95
 
88
- if (!isArrayType) return;
96
+ if (!isArrayType) {
97
+ return;
98
+ }
89
99
  } else {
90
100
  return;
91
101
  }
@@ -50,11 +50,15 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
50
50
  return {
51
51
  BinaryExpression: (node) => {
52
52
  // Check for `xs.length >= n` or `n <= xs.length`
53
- if (node.operator !== '>=' && node.operator !== '<=') return;
53
+ if (node.operator !== '>=' && node.operator !== '<=') {
54
+ return;
55
+ }
54
56
 
55
57
  // Defer to `prefer-arr-is-bounded-length-array` when this comparison is
56
58
  // the lower bound of a `min && max` pair on the same array.
57
- if (isPartOfBoundedLengthCheck(node, sourceCode)) return;
59
+ if (isPartOfBoundedLengthCheck(node, sourceCode)) {
60
+ return;
61
+ }
58
62
 
59
63
  // xs.length >= n or n <= xs.length
60
64
  const isLengthOnLeft = node.operator === '>=';
@@ -64,10 +68,14 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
64
68
  const valueSide = node[isLengthOnLeft ? 'right' : 'left'];
65
69
 
66
70
  // Check if lengthSide is accessing .length
67
- if (!isLengthAccess(lengthSide)) return;
71
+ if (!isLengthAccess(lengthSide)) {
72
+ return;
73
+ }
68
74
 
69
75
  // Only match integer literals or const variables initialized with integer literals
70
- if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) return;
76
+ if (!isIntegerLiteralOrConstant(valueSide, sourceCode)) {
77
+ return;
78
+ }
71
79
 
72
80
  // lengthSide is MemberExpression accessing .length
73
81
  const arrayExpression = lengthSide.object;
@@ -85,7 +93,9 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
85
93
  const isArrayType =
86
94
  checker.isArrayType(type) || checker.isTupleType(type);
87
95
 
88
- if (!isArrayType) return;
96
+ if (!isArrayType) {
97
+ return;
98
+ }
89
99
  } else {
90
100
  return;
91
101
  }
@@ -45,7 +45,9 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
45
45
  return {
46
46
  BinaryExpression: (node) => {
47
47
  // Check for `xs.length > 0` or `0 < xs.length`
48
- if (node.operator !== '>' && node.operator !== '<') return;
48
+ if (node.operator !== '>' && node.operator !== '<') {
49
+ return;
50
+ }
49
51
 
50
52
  const isLengthOnLeft = node.operator === '>';
51
53
 
@@ -79,7 +81,9 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
79
81
  const isArrayType =
80
82
  checker.isArrayType(type) || checker.isTupleType(type);
81
83
 
82
- if (!isArrayType) return;
84
+ if (!isArrayType) {
85
+ return;
86
+ }
83
87
  } else {
84
88
  return;
85
89
  }
@@ -190,7 +190,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
190
190
  ): boolean => {
191
191
  const tsNode = services?.esTreeNodeToTSNodeMap?.get(node);
192
192
 
193
- if (checker === undefined || tsNode === undefined) return true;
193
+ if (checker === undefined || tsNode === undefined) {
194
+ return true;
195
+ }
194
196
 
195
197
  const type = checker.getTypeAtLocation(tsNode);
196
198
 
@@ -227,14 +229,16 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
227
229
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
228
230
  accumulation: Accumulation,
229
231
  ): string | undefined => {
230
- if (callback.async || callback.generator) return undefined;
232
+ if (callback.async || callback.generator) {
233
+ return undefined;
234
+ }
231
235
 
232
236
  // `reduce`'s fourth parameter is the whole array, which `scan` never
233
237
  // hands its callback; an annotation on the accumulator describes that
234
238
  // array, and would be wrong on `scan`'s value parameter.
235
239
  if (
236
240
  callback.params.length < 2 ||
237
- callback.params.length > 3 ||
241
+ 3 < callback.params.length ||
238
242
  callback.params.some(
239
243
  (param) =>
240
244
  param.type !== AST_NODE_TYPES.Identifier ||
@@ -266,7 +270,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
266
270
  (variable) => variable.name === accumulatorParam.name,
267
271
  );
268
272
 
269
- if (accumulator === undefined) return undefined;
273
+ if (accumulator === undefined) {
274
+ return undefined;
275
+ }
270
276
 
271
277
  // `acc.at(-1)` is `T | undefined` only because `at` can go out of bounds,
272
278
  // which a seeded accumulator never does. So once the value `scan` carries
@@ -281,13 +287,19 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
281
287
  const identifier = reference.identifier;
282
288
 
283
289
  // The `...acc` / `Arr.toPushed(acc, …)` target the rewrite drops.
284
- if (identifier === accumulatorRef) continue;
290
+ if (identifier === accumulatorRef) {
291
+ continue;
292
+ }
285
293
 
286
- if (identifier.type !== AST_NODE_TYPES.Identifier) return undefined;
294
+ if (identifier.type !== AST_NODE_TYPES.Identifier) {
295
+ return undefined;
296
+ }
287
297
 
288
298
  const lastRead = enclosingLastRead(identifier);
289
299
 
290
- if (lastRead === undefined) return undefined;
300
+ if (lastRead === undefined) {
301
+ return undefined;
302
+ }
291
303
 
292
304
  const guard = carriesNullish ? undefined : nullishGuardAround(lastRead);
293
305
 
@@ -299,11 +311,15 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
299
311
 
300
312
  // Two reads inside one `?? ` — `acc.at(-1) ?? acc.at(-1)` — would give
301
313
  // ranges that contain one another, which no ordering of splices resolves.
302
- if (overlaps(mut_lastReads)) return undefined;
314
+ if (overlaps(mut_lastReads)) {
315
+ return undefined;
316
+ }
303
317
 
304
318
  // With no read of the previous value this is a `map` with a seed rather
305
319
  // than a scan, and the accumulator parameter would be left unused.
306
- if (mut_lastReads.length === 0) return undefined;
320
+ if (mut_lastReads.length === 0) {
321
+ return undefined;
322
+ }
307
323
 
308
324
  const parameterText = callback.params
309
325
  .map((param) => sourceCode.getText(param))
@@ -333,7 +349,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
333
349
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
334
350
  callback: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression,
335
351
  ): readonly TSESTree.Node[] | undefined => {
336
- if (!Arr.isFixedLengthArray(2, callback.params)) return undefined;
352
+ if (!Arr.isFixedLengthArray(2, callback.params)) {
353
+ return undefined;
354
+ }
337
355
 
338
356
  const [elementParam, indexParam] = callback.params;
339
357
 
@@ -358,7 +376,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
358
376
  return undefined;
359
377
  }
360
378
 
361
- if (elementVariable.references.length > 0) return undefined;
379
+ if (elementVariable.references.length > 0) {
380
+ return undefined;
381
+ }
362
382
 
363
383
  return indexVariable.references.map(
364
384
  (reference) => reference.identifier as TSESTree.Node,
@@ -395,11 +415,15 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
395
415
 
396
416
  switch (methodName) {
397
417
  case 'map': {
398
- if (rest.length > 0) break;
418
+ if (rest.length > 0) {
419
+ break;
420
+ }
399
421
 
400
422
  const indexReads = indexReadsOf(callback);
401
423
 
402
- if (indexReads === undefined) break;
424
+ if (indexReads === undefined) {
425
+ break;
426
+ }
403
427
 
404
428
  mut_candidates.push({
405
429
  call: node,
@@ -415,7 +439,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
415
439
  // Two arguments, so that the initial value is explicit: a `reduce`
416
440
  // without one starts from the first element and has no `scan`
417
441
  // spelling at all.
418
- if (rest.length !== 1 || !appendsToItsAccumulator(callback)) break;
442
+ if (rest.length !== 1 || !appendsToItsAccumulator(callback)) {
443
+ break;
444
+ }
419
445
 
420
446
  const [initial] = rest;
421
447
 
@@ -483,7 +509,9 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
483
509
  ),
484
510
  );
485
511
 
486
- if (rebuild === undefined) continue;
512
+ if (rebuild === undefined) {
513
+ continue;
514
+ }
487
515
 
488
516
  context.report({
489
517
  node: candidate.call,
@@ -605,7 +633,9 @@ const appendsToItsAccumulator = (
605
633
  ): boolean => {
606
634
  const [accumulatorParam] = callback.params;
607
635
 
608
- if (accumulatorParam?.type !== AST_NODE_TYPES.Identifier) return false;
636
+ if (accumulatorParam?.type !== AST_NODE_TYPES.Identifier) {
637
+ return false;
638
+ }
609
639
 
610
640
  const { body } = callback;
611
641
 
@@ -645,14 +675,18 @@ const accumulationOf = (
645
675
  ): Accumulation | undefined => {
646
676
  const [accumulatorParam] = callback.params;
647
677
 
648
- if (accumulatorParam?.type !== AST_NODE_TYPES.Identifier) return undefined;
678
+ if (accumulatorParam?.type !== AST_NODE_TYPES.Identifier) {
679
+ return undefined;
680
+ }
649
681
 
650
682
  const { body } = callback;
651
683
 
652
684
  // `[...acc, ELEMENT]` — exactly one spread and one new value, since `scan`
653
685
  // appends exactly one per step.
654
686
  if (body.type === AST_NODE_TYPES.ArrayExpression) {
655
- if (!Arr.isFixedLengthArray(2, body.elements)) return undefined;
687
+ if (!Arr.isFixedLengthArray(2, body.elements)) {
688
+ return undefined;
689
+ }
656
690
 
657
691
  const [spread, element] = body.elements;
658
692
 
@@ -61,7 +61,9 @@ export const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {
61
61
  const arrayExpression = node.callee.object;
62
62
 
63
63
  // Check if we have 2 arguments: reducer function and initial value 0
64
- if (!Arr.isFixedLengthTuple(2, node.arguments)) return;
64
+ if (!Arr.isFixedLengthTuple(2, node.arguments)) {
65
+ return;
66
+ }
65
67
 
66
68
  const reducer = node.arguments[0];
67
69
 
@@ -96,7 +98,9 @@ export const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {
96
98
 
97
99
  const checker = services?.program?.getTypeChecker();
98
100
 
99
- if (checker === undefined) return;
101
+ if (checker === undefined) {
102
+ return;
103
+ }
100
104
 
101
105
  // Case 1: (a, b) => a + b
102
106
  if (
@@ -189,7 +193,9 @@ export const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {
189
193
  mut_propName = leftProp.value;
190
194
  }
191
195
 
192
- if (mut_propName === undefined) return;
196
+ if (mut_propName === undefined) {
197
+ return;
198
+ }
193
199
 
194
200
  // Check if property type is number
195
201
  if (services?.program !== undefined && services.program !== null) {