eslint 10.0.0-alpha.1 → 10.0.0-rc.0

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.
@@ -53,8 +53,14 @@ module.exports = {
53
53
  description:
54
54
  "Whether to count a `this` declaration when the type is `void`.",
55
55
  },
56
+ countThis: {
57
+ enum: ["never", "except-void", "always"],
58
+ description:
59
+ "Whether to count a `this` declaration.",
60
+ },
56
61
  },
57
62
  additionalProperties: false,
63
+ not: { required: ["countVoidThis", "countThis"] },
58
64
  },
59
65
  ],
60
66
  },
@@ -68,7 +74,7 @@ module.exports = {
68
74
  const sourceCode = context.sourceCode;
69
75
  const option = context.options[0];
70
76
  let numParams = 3;
71
- let countVoidThis = false;
77
+ let countThis = "except-void";
72
78
 
73
79
  if (typeof option === "object") {
74
80
  if (
@@ -77,7 +83,12 @@ module.exports = {
77
83
  ) {
78
84
  numParams = option.maximum || option.max;
79
85
  }
80
- countVoidThis = option.countVoidThis;
86
+
87
+ countThis = option.countThis;
88
+ if (!countThis && Object.hasOwn(option, "countVoidThis")) {
89
+ countThis = option.countVoidThis ? "always" : "except-void";
90
+ }
91
+ countThis ||= "except-void";
81
92
  }
82
93
  if (typeof option === "number") {
83
94
  numParams = option;
@@ -90,17 +101,25 @@ module.exports = {
90
101
  * @private
91
102
  */
92
103
  function checkFunction(node) {
93
- const hasVoidThisParam =
104
+ const thisParam =
94
105
  node.params.length > 0 &&
95
106
  node.params[0].type === "Identifier" &&
96
- node.params[0].name === "this" &&
97
- node.params[0].typeAnnotation?.typeAnnotation.type ===
98
- "TSVoidKeyword";
107
+ node.params[0].name === "this"
108
+ ? node.params[0]
109
+ : null;
99
110
 
100
- const effectiveParamCount =
101
- hasVoidThisParam && !countVoidThis
102
- ? node.params.length - 1
103
- : node.params.length;
111
+ let effectiveParamCount = node.params.length;
112
+ if (thisParam) {
113
+ if (countThis === "never") {
114
+ effectiveParamCount = node.params.length - 1;
115
+ } else if (
116
+ countThis === "except-void" &&
117
+ thisParam.typeAnnotation?.typeAnnotation.type ===
118
+ "TSVoidKeyword"
119
+ ) {
120
+ effectiveParamCount = node.params.length - 1;
121
+ }
122
+ }
104
123
 
105
124
  if (effectiveParamCount > numParams) {
106
125
  context.report({
@@ -10,6 +10,30 @@
10
10
 
11
11
  const astUtils = require("./utils/ast-utils");
12
12
 
13
+ //------------------------------------------------------------------------------
14
+ // Helpers
15
+ //------------------------------------------------------------------------------
16
+
17
+ /**
18
+ * Format import names for error messages.
19
+ * @param {string[]} importNames The import names to format.
20
+ * @returns {string} The formatted import names.
21
+ */
22
+ function formatImportNames(importNames) {
23
+ return new Intl.ListFormat("en-US").format(
24
+ importNames.map(name => `'${name}'`),
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Returns "is" or "are" based on the number of import names.
30
+ * @param {string[]} importNames The import names to check.
31
+ * @returns {string} "is" if one import name, otherwise "are".
32
+ */
33
+ function isOrAre(importNames) {
34
+ return importNames.length === 1 ? "is" : "are";
35
+ }
36
+
13
37
  //------------------------------------------------------------------------------
14
38
  // Rule Definition
15
39
  //------------------------------------------------------------------------------
@@ -175,22 +199,22 @@ module.exports = {
175
199
  "'{{importName}}' import from '{{importSource}}' is restricted from being used by a pattern. {{customMessage}}",
176
200
 
177
201
  patternAndEverything:
178
- "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted from being used by a pattern.",
202
+ "* import is invalid because {{importNames}} from '{{importSource}}' {{isOrAre}} restricted from being used by a pattern.",
179
203
 
180
204
  patternAndEverythingWithRegexImportName:
181
205
  "* import is invalid because import name matching '{{importNames}}' pattern from '{{importSource}}' is restricted from being used.",
182
206
  patternAndEverythingWithCustomMessage:
183
207
  // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
184
- "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted from being used by a pattern. {{customMessage}}",
208
+ "* import is invalid because {{importNames}} from '{{importSource}}' {{isOrAre}} restricted from being used by a pattern. {{customMessage}}",
185
209
  patternAndEverythingWithRegexImportNameAndCustomMessage:
186
210
  // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
187
211
  "* import is invalid because import name matching '{{importNames}}' pattern from '{{importSource}}' is restricted from being used. {{customMessage}}",
188
212
 
189
213
  everything:
190
- "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.",
214
+ "* import is invalid because {{importNames}} from '{{importSource}}' {{isOrAre}} restricted.",
191
215
  everythingWithCustomMessage:
192
216
  // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
193
- "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}",
217
+ "* import is invalid because {{importNames}} from '{{importSource}}' {{isOrAre}} restricted. {{customMessage}}",
194
218
 
195
219
  importName:
196
220
  "'{{importName}}' import from '{{importSource}}' is restricted.",
@@ -199,16 +223,16 @@ module.exports = {
199
223
  "'{{importName}}' import from '{{importSource}}' is restricted. {{customMessage}}",
200
224
 
201
225
  allowedImportName:
202
- "'{{importName}}' import from '{{importSource}}' is restricted because only '{{allowedImportNames}}' import(s) is/are allowed.",
226
+ "'{{importName}}' import from '{{importSource}}' is restricted because only {{allowedImportNames}} {{isOrAre}} allowed.",
203
227
  allowedImportNameWithCustomMessage:
204
228
  // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
205
- "'{{importName}}' import from '{{importSource}}' is restricted because only '{{allowedImportNames}}' import(s) is/are allowed. {{customMessage}}",
229
+ "'{{importName}}' import from '{{importSource}}' is restricted because only {{allowedImportNames}} {{isOrAre}} allowed. {{customMessage}}",
206
230
 
207
231
  everythingWithAllowImportNames:
208
- "* import is invalid because only '{{allowedImportNames}}' from '{{importSource}}' is/are allowed.",
232
+ "* import is invalid because only {{allowedImportNames}} from '{{importSource}}' {{isOrAre}} allowed.",
209
233
  everythingWithAllowImportNamesAndCustomMessage:
210
234
  // eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
211
- "* import is invalid because only '{{allowedImportNames}}' from '{{importSource}}' is/are allowed. {{customMessage}}",
235
+ "* import is invalid because only {{allowedImportNames}} from '{{importSource}}' {{isOrAre}} allowed. {{customMessage}}",
212
236
 
213
237
  allowedImportNamePattern:
214
238
  "'{{importName}}' import from '{{importSource}}' is restricted because only imports that match the pattern '{{allowedImportNamePattern}}' are allowed from '{{importSource}}'.",
@@ -452,7 +476,10 @@ module.exports = {
452
476
  loc: specifier.loc,
453
477
  data: {
454
478
  importSource,
455
- importNames: restrictedImportNames,
479
+ importNames: formatImportNames(
480
+ restrictedImportNames,
481
+ ),
482
+ isOrAre: isOrAre(restrictedImportNames),
456
483
  customMessage,
457
484
  },
458
485
  });
@@ -465,7 +492,11 @@ module.exports = {
465
492
  loc: specifier.loc,
466
493
  data: {
467
494
  importSource,
468
- allowedImportNames,
495
+ allowedImportNames:
496
+ formatImportNames(
497
+ allowedImportNames,
498
+ ),
499
+ isOrAre: isOrAre(allowedImportNames),
469
500
  customMessage,
470
501
  },
471
502
  });
@@ -525,7 +556,11 @@ module.exports = {
525
556
  importSource,
526
557
  customMessage,
527
558
  importName,
528
- allowedImportNames,
559
+ allowedImportNames:
560
+ formatImportNames(
561
+ allowedImportNames,
562
+ ),
563
+ isOrAre: isOrAre(allowedImportNames),
529
564
  },
530
565
  });
531
566
  });
@@ -612,7 +647,10 @@ module.exports = {
612
647
  loc: specifier.loc,
613
648
  data: {
614
649
  importSource,
615
- importNames: restrictedImportNames,
650
+ importNames: formatImportNames(
651
+ restrictedImportNames,
652
+ ),
653
+ isOrAre: isOrAre(restrictedImportNames),
616
654
  customMessage,
617
655
  },
618
656
  });
@@ -625,7 +663,9 @@ module.exports = {
625
663
  loc: specifier.loc,
626
664
  data: {
627
665
  importSource,
628
- allowedImportNames,
666
+ allowedImportNames:
667
+ formatImportNames(allowedImportNames),
668
+ isOrAre: isOrAre(allowedImportNames),
629
669
  customMessage,
630
670
  },
631
671
  });
@@ -713,7 +753,9 @@ module.exports = {
713
753
  importSource,
714
754
  customMessage,
715
755
  importName,
716
- allowedImportNames,
756
+ allowedImportNames:
757
+ formatImportNames(allowedImportNames),
758
+ isOrAre: isOrAre(allowedImportNames),
717
759
  },
718
760
  });
719
761
  });
@@ -336,9 +336,12 @@ module.exports = {
336
336
  }
337
337
 
338
338
  if (
339
- targetAssignment.variable.references.some(
340
- ref => ref.identifier.type !== "Identifier",
341
- )
339
+ targetAssignment.variable.references.some(ref => {
340
+ const type = ref.identifier.type;
341
+ return (
342
+ type !== "Identifier" && type !== "JSXIdentifier"
343
+ );
344
+ })
342
345
  ) {
343
346
  /**
344
347
  * Skip checking for a variable that has at least one non-identifier reference.
@@ -529,7 +532,7 @@ module.exports = {
529
532
  TryStatement(node) {
530
533
  scopeStack.tryStatementBlocks.push(node.block);
531
534
  },
532
- Identifier(node) {
535
+ "Identifier, JSXIdentifier"(node) {
533
536
  for (const segment of scopeStack.currentSegments) {
534
537
  const segmentInfo = scopeStack.segments[segment.id];
535
538
 
@@ -539,7 +542,7 @@ module.exports = {
539
542
  segmentInfo.last = node;
540
543
  }
541
544
  },
542
- ":matches(VariableDeclarator[init!=null], AssignmentExpression, UpdateExpression):exit"(
545
+ "VariableDeclarator[init!=null], AssignmentExpression, UpdateExpression:exit"(
543
546
  node,
544
547
  ) {
545
548
  if (scopeStack.currentSegments.size === 0) {
@@ -704,60 +704,63 @@ function isKeywordToken(token) {
704
704
  }
705
705
 
706
706
  /**
707
- * Check to see if its a ES6 export declaration.
708
- * @param {ASTNode} astNode An AST node.
709
- * @returns {boolean} whether the given node represents an export declaration.
707
+ * Checks whether the given node represents an ES6 export declaration.
708
+ * @param {ASTNode} node A node to check.
709
+ * @returns {boolean} `true` if the node is an export declaration.
710
710
  * @private
711
711
  */
712
- function looksLikeExport(astNode) {
712
+ function isExportDeclaration(node) {
713
713
  return (
714
- astNode.type === "ExportDefaultDeclaration" ||
715
- astNode.type === "ExportNamedDeclaration" ||
716
- astNode.type === "ExportAllDeclaration" ||
717
- astNode.type === "ExportSpecifier"
714
+ node.type === "ExportDefaultDeclaration" ||
715
+ node.type === "ExportNamedDeclaration" ||
716
+ node.type === "ExportAllDeclaration"
718
717
  );
719
718
  }
720
719
 
721
720
  /**
722
- * Retrieves the JSDoc comment for a given node.
723
- * @param {ASTNode} node The AST node to get the comment for.
721
+ * Checks for the presence of a JSDoc comment for the given node and returns it.
722
+ * @param {ASTNode} node The node to get the comment for.
724
723
  * @param {SourceCode} sourceCode A SourceCode instance to get comments.
725
724
  * @returns {Token|null} The Block comment token containing the JSDoc comment for the given node or null if not found.
726
725
  * @private
727
726
  */
728
- function getJSDocComment(node, sourceCode) {
729
- /**
730
- * Checks for the presence of a JSDoc comment for the given node and returns it.
731
- * @param {ASTNode} astNode The AST node to get the comment for.
732
- * @returns {Token|null} The Block comment token containing the JSDoc comment for the given node or null if not found.
733
- * @private
734
- */
735
- function findJSDocComment(astNode) {
736
- const tokenBefore = sourceCode.getTokenBefore(astNode, {
737
- includeComments: true,
738
- });
727
+ function findJSDocComment(node, sourceCode) {
728
+ const tokenBefore = sourceCode.getTokenBefore(node, {
729
+ includeComments: true,
730
+ });
739
731
 
740
- if (
741
- tokenBefore &&
742
- isCommentToken(tokenBefore) &&
743
- tokenBefore.type === "Block" &&
744
- tokenBefore.value.charAt(0) === "*" &&
745
- astNode.loc.start.line - tokenBefore.loc.end.line <= 1
746
- ) {
747
- return tokenBefore;
748
- }
749
-
750
- return null;
732
+ if (
733
+ tokenBefore &&
734
+ tokenBefore.type === "Block" &&
735
+ tokenBefore.value.charAt(0) === "*" &&
736
+ node.loc.start.line - tokenBefore.loc.end.line <= 1
737
+ ) {
738
+ return tokenBefore;
751
739
  }
740
+
741
+ return null;
742
+ }
743
+
744
+ /**
745
+ * Retrieves the JSDoc comment for a given node.
746
+ * @param {ASTNode} node The node to get the comment for.
747
+ * @param {SourceCode} sourceCode A SourceCode instance to get comments.
748
+ * @returns {Token|null} The Block comment token containing the JSDoc comment for the given node or null if not found.
749
+ * @private
750
+ */
751
+ function getJSDocComment(node, sourceCode) {
752
752
  let parent = node.parent;
753
753
 
754
754
  switch (node.type) {
755
755
  case "ClassDeclaration":
756
756
  case "FunctionDeclaration":
757
- return findJSDocComment(looksLikeExport(parent) ? parent : node);
757
+ return findJSDocComment(
758
+ isExportDeclaration(parent) ? parent : node,
759
+ sourceCode,
760
+ );
758
761
 
759
762
  case "ClassExpression":
760
- return findJSDocComment(parent.parent);
763
+ return findJSDocComment(parent.parent, sourceCode);
761
764
 
762
765
  case "ArrowFunctionExpression":
763
766
  case "FunctionExpression":
@@ -783,11 +786,11 @@ function getJSDocComment(node, sourceCode) {
783
786
  parent.type !== "FunctionDeclaration" &&
784
787
  parent.type !== "Program"
785
788
  ) {
786
- return findJSDocComment(parent);
789
+ return findJSDocComment(parent, sourceCode);
787
790
  }
788
791
  }
789
792
 
790
- return findJSDocComment(node);
793
+ return findJSDocComment(node, sourceCode);
791
794
 
792
795
  // falls through
793
796
  default:
@@ -53,7 +53,6 @@ import type {
53
53
  EcmaVersion as CoreEcmaVersion,
54
54
  ConfigOverride as CoreConfigOverride,
55
55
  ProcessorFile as CoreProcessorFile,
56
- JavaScriptParserOptionsConfig,
57
56
  RulesMeta,
58
57
  RuleConfig,
59
58
  RuleTextEditor,
@@ -115,7 +114,7 @@ export namespace AST {
115
114
  end: ESTree.Position;
116
115
  }
117
116
 
118
- type Range = [number, number];
117
+ type Range = SourceRange;
119
118
 
120
119
  interface Program extends ESTree.Program {
121
120
  comments: ESTree.Comment[];
@@ -125,6 +124,11 @@ export namespace AST {
125
124
  }
126
125
  }
127
126
 
127
+ interface JSXIdentifier extends ESTree.BaseNode {
128
+ type: "JSXIdentifier";
129
+ name: string;
130
+ }
131
+
128
132
  export namespace Scope {
129
133
  interface ScopeManager {
130
134
  scopes: Scope[];
@@ -134,7 +138,7 @@ export namespace Scope {
134
138
 
135
139
  getDeclaredVariables(node: ESTree.Node): Variable[];
136
140
 
137
- addGlobals(names: string[]): void;
141
+ addGlobals(names: ReadonlyArray<string>): void;
138
142
  }
139
143
 
140
144
  interface Scope {
@@ -150,8 +154,7 @@ export namespace Scope {
150
154
  | "global"
151
155
  | "module"
152
156
  | "switch"
153
- | "with"
154
- | "TDZ";
157
+ | "with";
155
158
  isStrict: boolean;
156
159
  upper: Scope | null;
157
160
  childScopes: Scope[];
@@ -177,11 +180,11 @@ export namespace Scope {
177
180
  }
178
181
 
179
182
  interface Reference {
180
- identifier: ESTree.Identifier;
183
+ identifier: ESTree.Identifier | JSXIdentifier;
181
184
  from: Scope;
182
185
  resolved: Variable | null;
183
- writeExpr: ESTree.Node | null;
184
- init: boolean;
186
+ writeExpr?: ESTree.Expression | null;
187
+ init?: boolean;
185
188
 
186
189
  isWrite(): boolean;
187
190
 
@@ -230,7 +233,6 @@ export namespace Scope {
230
233
  | ESTree.ArrowFunctionExpression;
231
234
  parent: null;
232
235
  }
233
- | { type: "TDZ"; node: any; parent: null }
234
236
  | {
235
237
  type: "Variable";
236
238
  node: ESTree.VariableDeclarator;
@@ -807,23 +809,23 @@ export class Linter {
807
809
 
808
810
  verify(
809
811
  code: SourceCode | string,
810
- config: Linter.LegacyConfig | Linter.Config | Linter.Config[],
812
+ config: Linter.Config | Linter.Config[],
811
813
  filename?: string,
812
814
  ): Linter.LintMessage[];
813
815
  verify(
814
816
  code: SourceCode | string,
815
- config: Linter.LegacyConfig | Linter.Config | Linter.Config[],
817
+ config: Linter.Config | Linter.Config[],
816
818
  options: Linter.LintOptions,
817
819
  ): Linter.LintMessage[];
818
820
 
819
821
  verifyAndFix(
820
822
  code: string,
821
- config: Linter.LegacyConfig | Linter.Config | Linter.Config[],
823
+ config: Linter.Config | Linter.Config[],
822
824
  filename?: string,
823
825
  ): Linter.FixReport;
824
826
  verifyAndFix(
825
827
  code: string,
826
- config: Linter.LegacyConfig | Linter.Config | Linter.Config[],
828
+ config: Linter.Config | Linter.Config[],
827
829
  options: Linter.FixOptions,
828
830
  ): Linter.FixReport;
829
831
 
@@ -930,7 +932,43 @@ export namespace Linter {
930
932
  *
931
933
  * @see [Specifying Parser Options](https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options)
932
934
  */
933
- type ParserOptions = JavaScriptParserOptionsConfig;
935
+ interface ParserOptions {
936
+ /**
937
+ * Allow the use of reserved words as identifiers (if `ecmaVersion` is 3).
938
+ *
939
+ * @default false
940
+ */
941
+ allowReserved?: boolean | undefined;
942
+ /**
943
+ * An object indicating which additional language features you'd like to use.
944
+ *
945
+ * @see https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options
946
+ */
947
+ ecmaFeatures?:
948
+ | {
949
+ /**
950
+ * Allow `return` statements in the global scope.
951
+ *
952
+ * @default false
953
+ */
954
+ globalReturn?: boolean | undefined;
955
+ /**
956
+ * Enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is 5 or greater).
957
+ *
958
+ * @default false
959
+ */
960
+ impliedStrict?: boolean | undefined;
961
+ /**
962
+ * Enable [JSX](https://facebook.github.io/jsx/).
963
+ *
964
+ * @default false
965
+ */
966
+ jsx?: boolean | undefined;
967
+ [key: string]: any;
968
+ }
969
+ | undefined;
970
+ [key: string]: any;
971
+ }
934
972
 
935
973
  /**
936
974
  * Options used for linting code with `Linter#verify` and `Linter#verifyAndFix`.
@@ -1256,9 +1294,8 @@ export namespace ESLint {
1256
1294
  foundWarnings: number;
1257
1295
  }
1258
1296
 
1259
- interface LintResultData {
1297
+ interface LintResultData extends ResultsMeta {
1260
1298
  cwd: string;
1261
- maxWarningsExceeded?: MaxWarningsExceeded | undefined;
1262
1299
  rulesMeta: {
1263
1300
  [ruleId: string]: Rule.RuleMetaData;
1264
1301
  };
@@ -1290,6 +1327,14 @@ export namespace ESLint {
1290
1327
  * Metadata about results for formatters.
1291
1328
  */
1292
1329
  interface ResultsMeta {
1330
+ /**
1331
+ * Whether or not to use color in the formatter output.
1332
+ * - If `--color` was set, this property is `true`.
1333
+ * - If `--no-color` was set, it is `false`.
1334
+ * - If neither option was provided, the property is omitted.
1335
+ */
1336
+ color?: boolean | undefined;
1337
+
1293
1338
  /**
1294
1339
  * Present if the maxWarnings threshold was exceeded.
1295
1340
  */
@@ -1301,9 +1346,9 @@ export namespace ESLint {
1301
1346
  /**
1302
1347
  * Used to call the underlying formatter.
1303
1348
  * @param results An array of lint results to format.
1304
- * @param resultsMeta An object with an optional `maxWarningsExceeded` property that will be
1349
+ * @param resultsMeta An object with optional `color` and `maxWarningsExceeded` properties that will be
1305
1350
  * passed to the underlying formatter function along with other properties set by ESLint.
1306
- * This argument can be omitted if `maxWarningsExceeded` is not needed.
1351
+ * This argument can be omitted if `color` and `maxWarningsExceeded` are not needed.
1307
1352
  * @return The formatter output.
1308
1353
  */
1309
1354
  format(
@@ -1332,9 +1377,10 @@ export namespace ESLint {
1332
1377
 
1333
1378
  // #endregion
1334
1379
 
1335
- export function loadESLint(options?: {
1336
- useFlatConfig?: boolean | undefined;
1337
- }): Promise<typeof ESLint>;
1380
+ /**
1381
+ * Loads the correct `ESLint` constructor.
1382
+ */
1383
+ export function loadESLint(): Promise<typeof ESLint>;
1338
1384
 
1339
1385
  // #region RuleTester
1340
1386
 
@@ -1342,6 +1388,9 @@ export class RuleTester {
1342
1388
  static describe: ((...args: any) => any) | null;
1343
1389
  static it: ((...args: any) => any) | null;
1344
1390
  static itOnly: ((...args: any) => any) | null;
1391
+ static setDefaultConfig(config: Linter.Config): void;
1392
+ static getDefaultConfig(): Linter.Config;
1393
+ static resetDefaultConfig(): void;
1345
1394
 
1346
1395
  constructor(config?: Linter.Config);
1347
1396
 
@@ -1351,6 +1400,32 @@ export class RuleTester {
1351
1400
  tests: {
1352
1401
  valid: Array<string | RuleTester.ValidTestCase>;
1353
1402
  invalid: RuleTester.InvalidTestCase[];
1403
+ /**
1404
+ * Additional assertions for the "error" matchers of invalid test cases to enforce consistency.
1405
+ */
1406
+ assertionOptions?: {
1407
+ /**
1408
+ * If true, each `errors` block must check the expected error
1409
+ * message, either via a string in the `errors` array, or via
1410
+ * `message`/`messageId` in an errors object.
1411
+ * `"message"`/`"messageId"` can be used to further limit the
1412
+ * message assertions to the respective versions.
1413
+ */
1414
+ requireMessage?: boolean | "message" | "messageId";
1415
+ /**
1416
+ * If true, each `errors` block must be an array of objects,
1417
+ * that each check all location properties `line`, `column`,
1418
+ * `endLine`, `endColumn`, the later may be omitted, if the
1419
+ * error does not contain them.
1420
+ */
1421
+ requireLocation?: boolean;
1422
+ /**
1423
+ * If true, each error and suggestion with a `messageId` must specify a `data`
1424
+ * property if the referenced message contains placeholders.
1425
+ * `"error"` and `"suggestion" limit the assertion to errors and suggestions respectively.
1426
+ */
1427
+ requireData?: boolean | "error" | "suggestion";
1428
+ };
1354
1429
  },
1355
1430
  ): void;
1356
1431
 
@@ -1360,14 +1435,22 @@ export class RuleTester {
1360
1435
  }
1361
1436
 
1362
1437
  export namespace RuleTester {
1363
- interface ValidTestCase {
1438
+ interface ValidTestCase
1439
+ extends Omit<
1440
+ Linter.Config,
1441
+ | "name"
1442
+ | "basePath"
1443
+ | "files"
1444
+ | "ignores"
1445
+ | "linterOptions"
1446
+ | "plugins"
1447
+ | "rules"
1448
+ > {
1364
1449
  name?: string;
1365
1450
  code: string;
1366
- options?: any;
1451
+ options?: any[];
1367
1452
  filename?: string | undefined;
1368
1453
  only?: boolean;
1369
- languageOptions?: Linter.LanguageOptions | undefined;
1370
- settings?: { [name: string]: any } | undefined;
1371
1454
  before?: () => void;
1372
1455
  after?: () => void;
1373
1456
  }
@@ -1380,7 +1463,7 @@ export namespace RuleTester {
1380
1463
  }
1381
1464
 
1382
1465
  interface InvalidTestCase extends ValidTestCase {
1383
- errors: number | Array<TestCaseError | string>;
1466
+ errors: number | Array<TestCaseError | string | RegExp>;
1384
1467
  output?: string | null | undefined;
1385
1468
  }
1386
1469
 
@@ -1392,7 +1475,7 @@ export namespace RuleTester {
1392
1475
  column?: number | undefined;
1393
1476
  endLine?: number | undefined;
1394
1477
  endColumn?: number | undefined;
1395
- suggestions?: SuggestionOutput[] | undefined;
1478
+ suggestions?: SuggestionOutput[] | number | undefined;
1396
1479
  }
1397
1480
  }
1398
1481
 
@@ -1858,9 +1858,14 @@ export interface ESLintRules extends Linter.RulesRecord {
1858
1858
  */
1859
1859
  max: number;
1860
1860
  /**
1861
+ * @deprecated Replaced with `countThis'
1861
1862
  * @default false
1862
1863
  */
1863
1864
  countVoidThis: boolean;
1865
+ /**
1866
+ * @default "except-void"
1867
+ */
1868
+ countThis: "always" | "never" | "except-void";
1864
1869
  }>,
1865
1870
  ]
1866
1871
  >;
@@ -31,4 +31,4 @@ import { Rule } from "./index.js";
31
31
  export const builtinRules: Map<string, Rule.RuleModule>;
32
32
 
33
33
  /** @deprecated */
34
- export function shouldUseFlatConfig(): Promise<boolean>;
34
+ export function shouldUseFlatConfig(): Promise<true>;