eslint 9.27.0 → 9.28.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.
@@ -24,6 +24,23 @@ const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
24
24
  const SENTINEL_TYPE =
25
25
  /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
26
26
 
27
+ // TS-specific node types
28
+ const TYPES_HOISTED_NODES = new Set([
29
+ "TSInterfaceDeclaration",
30
+ "TSTypeAliasDeclaration",
31
+ ]);
32
+
33
+ // TS-specific function variable def types
34
+ const ALLOWED_FUNCTION_VARIABLE_DEF_TYPES = new Set([
35
+ "TSCallSignatureDeclaration",
36
+ "TSFunctionType",
37
+ "TSMethodSignature",
38
+ "TSEmptyBodyFunctionExpression",
39
+ "TSDeclareFunction",
40
+ "TSConstructSignatureDeclaration",
41
+ "TSConstructorType",
42
+ ]);
43
+
27
44
  //------------------------------------------------------------------------------
28
45
  // Rule Definition
29
46
  //------------------------------------------------------------------------------
@@ -32,6 +49,8 @@ const SENTINEL_TYPE =
32
49
  module.exports = {
33
50
  meta: {
34
51
  type: "suggestion",
52
+ dialects: ["typescript", "javascript"],
53
+ language: "javascript",
35
54
 
36
55
  defaultOptions: [
37
56
  {
@@ -39,6 +58,8 @@ module.exports = {
39
58
  builtinGlobals: false,
40
59
  hoist: "functions",
41
60
  ignoreOnInitialization: false,
61
+ ignoreTypeValueShadow: true,
62
+ ignoreFunctionTypeParameterNameValueShadow: true,
42
63
  },
43
64
  ],
44
65
 
@@ -54,7 +75,15 @@ module.exports = {
54
75
  type: "object",
55
76
  properties: {
56
77
  builtinGlobals: { type: "boolean" },
57
- hoist: { enum: ["all", "functions", "never"] },
78
+ hoist: {
79
+ enum: [
80
+ "all",
81
+ "functions",
82
+ "never",
83
+ "types",
84
+ "functions-and-types",
85
+ ],
86
+ },
58
87
  allow: {
59
88
  type: "array",
60
89
  items: {
@@ -62,6 +91,10 @@ module.exports = {
62
91
  },
63
92
  },
64
93
  ignoreOnInitialization: { type: "boolean" },
94
+ ignoreTypeValueShadow: { type: "boolean" },
95
+ ignoreFunctionTypeParameterNameValueShadow: {
96
+ type: "boolean",
97
+ },
65
98
  },
66
99
  additionalProperties: false,
67
100
  },
@@ -75,10 +108,112 @@ module.exports = {
75
108
  },
76
109
 
77
110
  create(context) {
78
- const [{ builtinGlobals, hoist, allow, ignoreOnInitialization }] =
79
- context.options;
111
+ const [
112
+ {
113
+ builtinGlobals,
114
+ hoist,
115
+ allow,
116
+ ignoreOnInitialization,
117
+ ignoreTypeValueShadow,
118
+ ignoreFunctionTypeParameterNameValueShadow,
119
+ },
120
+ ] = context.options;
80
121
  const sourceCode = context.sourceCode;
81
122
 
123
+ /**
124
+ * Check if a scope is a TypeScript module augmenting the global namespace.
125
+ * @param {Scope} scope The scope to check
126
+ * @returns {boolean} Whether the scope is a global augmentation
127
+ */
128
+ function isGlobalAugmentation(scope) {
129
+ return (
130
+ scope.block.kind === "global" ||
131
+ (!!scope.upper && isGlobalAugmentation(scope.upper))
132
+ );
133
+ }
134
+
135
+ /**
136
+ * Check if variable is a `this` parameter.
137
+ * @param {Object} variable The variable to check
138
+ * @returns {boolean} Whether the variable is a this parameter
139
+ */
140
+ function isThisParam(variable) {
141
+ return variable.name === "this";
142
+ }
143
+
144
+ /**
145
+ * Checks if type and value shadows each other
146
+ * @param {Object} variable The variable to check
147
+ * @param {Object} shadowedVariable The shadowed variable
148
+ * @returns {boolean} Whether it's a type/value shadow case to ignore
149
+ */
150
+ function isTypeValueShadow(variable, shadowedVariable) {
151
+ if (ignoreTypeValueShadow !== true) {
152
+ return false;
153
+ }
154
+
155
+ if (!("isValueVariable" in variable)) {
156
+ return false;
157
+ }
158
+
159
+ const firstDefinition = shadowedVariable.defs[0];
160
+
161
+ // Check if shadowedVariable is a type import
162
+ const isTypeImport =
163
+ firstDefinition &&
164
+ firstDefinition.parent?.type === "ImportDeclaration" &&
165
+ (firstDefinition.parent.importKind === "type" ||
166
+ firstDefinition.parent.specifiers.some(
167
+ s => s.importKind === "type",
168
+ ));
169
+
170
+ const isShadowedValue =
171
+ !firstDefinition ||
172
+ (isTypeImport ? false : shadowedVariable.isValueVariable);
173
+
174
+ return variable.isValueVariable !== isShadowedValue;
175
+ }
176
+
177
+ /**
178
+ * Checks if it's a function type parameter shadow
179
+ * @param {Object} variable The variable to check
180
+ * @returns {boolean} Whether it's a function type parameter shadow case to ignore
181
+ */
182
+ function isFunctionTypeParameterNameValueShadow(variable) {
183
+ if (ignoreFunctionTypeParameterNameValueShadow !== true) {
184
+ return false;
185
+ }
186
+
187
+ return variable.defs.some(def =>
188
+ ALLOWED_FUNCTION_VARIABLE_DEF_TYPES.has(def.node.type),
189
+ );
190
+ }
191
+
192
+ /**
193
+ * Checks if the variable is a generic of a static method
194
+ * @param {Object} variable The variable to check
195
+ * @returns {boolean} Whether the variable is a generic of a static method
196
+ */
197
+ function isTypeParameterOfStaticMethod(variable) {
198
+ const typeParameter = variable.identifiers[0].parent;
199
+ const typeParameterDecl = typeParameter.parent;
200
+ if (typeParameterDecl.type !== "TSTypeParameterDeclaration") {
201
+ return false;
202
+ }
203
+ const functionExpr = typeParameterDecl.parent;
204
+ const methodDefinition = functionExpr.parent;
205
+ return methodDefinition.static;
206
+ }
207
+
208
+ /**
209
+ * Checks for static method generic shadowing class generic
210
+ * @param {Object} variable The variable to check
211
+ * @returns {boolean} Whether it's a static method generic shadowing class generic
212
+ */
213
+ function isGenericOfAStaticMethodShadow(variable) {
214
+ return isTypeParameterOfStaticMethod(variable);
215
+ }
216
+
82
217
  /**
83
218
  * Checks whether or not a given location is inside of the range of a given node.
84
219
  * @param {ASTNode} node An node to check.
@@ -114,7 +249,7 @@ module.exports = {
114
249
  function getOuterScope(scope) {
115
250
  const upper = scope.upper;
116
251
 
117
- if (upper.type === "function-expression-name") {
252
+ if (upper && upper.type === "function-expression-name") {
118
253
  return upper.upper;
119
254
  }
120
255
  return upper;
@@ -284,6 +419,21 @@ module.exports = {
284
419
  const inner = getNameRange(variable);
285
420
  const outer = getNameRange(scopeVar);
286
421
 
422
+ if (!outer || inner[1] >= outer[0]) {
423
+ return false;
424
+ }
425
+
426
+ if (hoist === "types") {
427
+ return !TYPES_HOISTED_NODES.has(outerDef.node.type);
428
+ }
429
+
430
+ if (hoist === "functions-and-types") {
431
+ return (
432
+ outerDef.node.type !== "FunctionDeclaration" &&
433
+ !TYPES_HOISTED_NODES.has(outerDef.node.type)
434
+ );
435
+ }
436
+
287
437
  return (
288
438
  inner &&
289
439
  outer &&
@@ -295,12 +445,111 @@ module.exports = {
295
445
  );
296
446
  }
297
447
 
448
+ /**
449
+ * Checks if the initialization of a variable has the declare modifier in a
450
+ * definition file.
451
+ * @param {Object} variable The variable to check
452
+ * @returns {boolean} Whether the variable is declared in a definition file
453
+ */
454
+ function isDeclareInDTSFile(variable) {
455
+ const fileName = context.filename;
456
+ if (
457
+ !fileName.endsWith(".d.ts") &&
458
+ !fileName.endsWith(".d.cts") &&
459
+ !fileName.endsWith(".d.mts")
460
+ ) {
461
+ return false;
462
+ }
463
+ return variable.defs.some(
464
+ def =>
465
+ (def.type === "Variable" && def.parent.declare) ||
466
+ (def.type === "ClassName" && def.node.declare) ||
467
+ (def.type === "TSEnumName" && def.node.declare) ||
468
+ (def.type === "TSModuleName" && def.node.declare),
469
+ );
470
+ }
471
+
472
+ /**
473
+ * Checks if a variable is a duplicate of an enum name in the enum scope
474
+ * @param {Object} variable The variable to check
475
+ * @returns {boolean} Whether it's a duplicate enum name variable
476
+ */
477
+ function isDuplicatedEnumNameVariable(variable) {
478
+ const block = variable.scope.block;
479
+
480
+ return (
481
+ block.type === "TSEnumDeclaration" &&
482
+ block.id === variable.identifiers[0]
483
+ );
484
+ }
485
+
486
+ /**
487
+ * Check if this is an external module declaration merging with a type import
488
+ * @param {Scope} scope Current scope
489
+ * @param {Object} variable Current variable
490
+ * @param {Object} shadowedVariable Shadowed variable
491
+ * @returns {boolean} Whether it's an external declaration merging
492
+ */
493
+ function isExternalDeclarationMerging(
494
+ scope,
495
+ variable,
496
+ shadowedVariable,
497
+ ) {
498
+ const firstDefinition = shadowedVariable.defs[0];
499
+
500
+ if (!firstDefinition || !firstDefinition.parent) {
501
+ return false;
502
+ }
503
+
504
+ // Check if the shadowed variable is a type import
505
+ const isTypeImport =
506
+ firstDefinition.parent.type === "ImportDeclaration" &&
507
+ (firstDefinition.parent.importKind === "type" ||
508
+ firstDefinition.parent.specifiers?.some(
509
+ s =>
510
+ s.type === "ImportSpecifier" &&
511
+ s.importKind === "type" &&
512
+ s.local.name === shadowedVariable.name,
513
+ ));
514
+
515
+ if (!isTypeImport) {
516
+ return false;
517
+ }
518
+
519
+ // Check if the current variable is within a module declaration
520
+ const moduleDecl = findSelfOrAncestor(
521
+ variable.identifiers[0]?.parent,
522
+ node => node.type === "TSModuleDeclaration",
523
+ );
524
+
525
+ if (!moduleDecl) {
526
+ return false;
527
+ }
528
+
529
+ /*
530
+ * Module declaration merging should only happen within the same module
531
+ * Check if the module name matches the import source
532
+ */
533
+ const importSource = firstDefinition.parent.source.value;
534
+ const moduleName =
535
+ moduleDecl.id.type === "Literal"
536
+ ? moduleDecl.id.value
537
+ : moduleDecl.id.name;
538
+
539
+ return importSource === moduleName;
540
+ }
541
+
298
542
  /**
299
543
  * Checks the current context for shadowed variables.
300
544
  * @param {Scope} scope Fixme
301
545
  * @returns {void}
302
546
  */
303
547
  function checkForShadows(scope) {
548
+ // ignore global augmentation
549
+ if (isGlobalAugmentation(scope)) {
550
+ return;
551
+ }
552
+
304
553
  const variables = scope.variables;
305
554
 
306
555
  for (let i = 0; i < variables.length; ++i) {
@@ -310,7 +559,10 @@ module.exports = {
310
559
  if (
311
560
  variable.identifiers.length === 0 ||
312
561
  isDuplicatedClassNameVariable(variable) ||
313
- isAllowed(variable)
562
+ isDuplicatedEnumNameVariable(variable) ||
563
+ isAllowed(variable) ||
564
+ isDeclareInDTSFile(variable) ||
565
+ isThisParam(variable)
314
566
  ) {
315
567
  continue;
316
568
  }
@@ -330,7 +582,11 @@ module.exports = {
330
582
  ignoreOnInitialization &&
331
583
  isInitPatternNode(variable, shadowed)
332
584
  ) &&
333
- !(hoist !== "all" && isInTdz(variable, shadowed))
585
+ !(hoist !== "all" && isInTdz(variable, shadowed)) &&
586
+ !isTypeValueShadow(variable, shadowed) &&
587
+ !isFunctionTypeParameterNameValueShadow(variable) &&
588
+ !isGenericOfAStaticMethodShadow(variable, shadowed) &&
589
+ !isExternalDeclarationMerging(scope, variable, shadowed)
334
590
  ) {
335
591
  const location = getDeclaredLocation(shadowed);
336
592
  const messageId = location.global
@@ -31,17 +31,25 @@ module.exports = {
31
31
 
32
32
  create(context) {
33
33
  const sourceCode = context.sourceCode;
34
+ let insideDeclareModule = false;
34
35
 
35
36
  return {
37
+ "TSModuleDeclaration[declare=true]"() {
38
+ insideDeclareModule = true;
39
+ },
40
+ "TSModuleDeclaration[declare=true]:exit"() {
41
+ insideDeclareModule = false;
42
+ },
36
43
  VariableDeclarator(node) {
37
44
  /** @type {import('estree').VariableDeclaration} */
38
45
  const declaration = node.parent;
39
- const shouldCheck =
40
- !node.init &&
41
- node.id.type === "Identifier" &&
42
- declaration.kind !== "const" &&
43
- !declaration.declare;
44
- if (!shouldCheck) {
46
+ const shouldSkip =
47
+ node.init ||
48
+ node.id.type !== "Identifier" ||
49
+ declaration.kind === "const" ||
50
+ declaration.declare ||
51
+ insideDeclareModule;
52
+ if (shouldSkip) {
45
53
  return;
46
54
  }
47
55
  const [variable] = sourceCode.getDeclaredVariables(node);
@@ -30,6 +30,9 @@ function parseOptions(options) {
30
30
  classes: true,
31
31
  variables: true,
32
32
  allowNamedExports: false,
33
+ enums: true,
34
+ typedefs: true,
35
+ ignoreTypeReferences: true,
33
36
  };
34
37
  }
35
38
 
@@ -208,6 +211,57 @@ function isEvaluatedDuringInitialization(reference) {
208
211
  return false;
209
212
  }
210
213
 
214
+ /**
215
+ * check whether the reference contains a type query.
216
+ * @param {ASTNode} node Identifier node to check.
217
+ * @returns {boolean} true if reference contains type query.
218
+ */
219
+ function referenceContainsTypeQuery(node) {
220
+ switch (node.type) {
221
+ case "TSTypeQuery":
222
+ return true;
223
+
224
+ case "TSQualifiedName":
225
+ case "Identifier":
226
+ return referenceContainsTypeQuery(node.parent);
227
+
228
+ default:
229
+ // if we find a different node, there's no chance that we're in a TSTypeQuery
230
+ return false;
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Decorators are transpiled such that the decorator is placed after the class declaration
236
+ * So it is considered safe
237
+ * @param {Variable} variable The variable to check.
238
+ * @param {Reference} reference The reference to check.
239
+ * @returns {boolean} `true` if the reference is in a class decorator.
240
+ */
241
+ function isClassRefInClassDecorator(variable, reference) {
242
+ if (variable.defs[0].type !== "ClassName") {
243
+ return false;
244
+ }
245
+
246
+ if (
247
+ !variable.defs[0].node.decorators ||
248
+ variable.defs[0].node.decorators.length === 0
249
+ ) {
250
+ return false;
251
+ }
252
+
253
+ for (const deco of variable.defs[0].node.decorators) {
254
+ if (
255
+ reference.identifier.range[0] >= deco.range[0] &&
256
+ reference.identifier.range[1] <= deco.range[1]
257
+ ) {
258
+ return true;
259
+ }
260
+ }
261
+
262
+ return false;
263
+ }
264
+
211
265
  //------------------------------------------------------------------------------
212
266
  // Rule Definition
213
267
  //------------------------------------------------------------------------------
@@ -237,6 +291,9 @@ module.exports = {
237
291
  classes: { type: "boolean" },
238
292
  variables: { type: "boolean" },
239
293
  allowNamedExports: { type: "boolean" },
294
+ enums: { type: "boolean" },
295
+ typedefs: { type: "boolean" },
296
+ ignoreTypeReferences: { type: "boolean" },
240
297
  },
241
298
  additionalProperties: false,
242
299
  },
@@ -250,6 +307,9 @@ module.exports = {
250
307
  functions: true,
251
308
  variables: true,
252
309
  allowNamedExports: false,
310
+ enums: true,
311
+ typedefs: true,
312
+ ignoreTypeReferences: true,
253
313
  },
254
314
  ],
255
315
 
@@ -310,6 +370,41 @@ module.exports = {
310
370
  return false;
311
371
  }
312
372
 
373
+ if (!options.enums && definitionType === "TSEnumName") {
374
+ return false;
375
+ }
376
+
377
+ if (!options.typedefs && definitionType === "Type") {
378
+ return false;
379
+ }
380
+
381
+ if (
382
+ options.ignoreTypeReferences &&
383
+ (referenceContainsTypeQuery(identifier) ||
384
+ identifier.parent.type === "TSTypeReference")
385
+ ) {
386
+ return false;
387
+ }
388
+
389
+ // skip nested namespace aliases as variable references
390
+ if (identifier.parent.type === "TSQualifiedName") {
391
+ let currentNode = identifier.parent;
392
+
393
+ while (currentNode.type === "TSQualifiedName") {
394
+ currentNode = currentNode.left;
395
+ }
396
+
397
+ if (currentNode === identifier) {
398
+ return true;
399
+ }
400
+
401
+ return false;
402
+ }
403
+
404
+ if (isClassRefInClassDecorator(variable, reference)) {
405
+ return false;
406
+ }
407
+
313
408
  return true;
314
409
  }
315
410
 
@@ -326,7 +421,8 @@ module.exports = {
326
421
  if (
327
422
  reference.identifier.range[1] <
328
423
  definitionIdentifier.range[1] ||
329
- isEvaluatedDuringInitialization(reference)
424
+ (isEvaluatedDuringInitialization(reference) &&
425
+ reference.identifier.parent.type !== "TSTypeReference")
330
426
  ) {
331
427
  context.report({
332
428
  node: reference.identifier,
@@ -151,6 +151,8 @@ function hasDuplicateParams(paramsList) {
151
151
  module.exports = {
152
152
  meta: {
153
153
  type: "suggestion",
154
+ dialects: ["javascript", "typescript"],
155
+ language: "javascript",
154
156
 
155
157
  defaultOptions: [
156
158
  { allowNamedFunctions: false, allowUnboundThis: true },
@@ -308,6 +310,13 @@ module.exports = {
308
310
  return;
309
311
  }
310
312
 
313
+ if (
314
+ node.params.length &&
315
+ node.params[0].name === "this"
316
+ ) {
317
+ return;
318
+ }
319
+
311
320
  // Remove `.bind(this)` if exists.
312
321
  if (callbackInfo.isLexicalThis) {
313
322
  const memberNode = node.parent;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @fileoverview Emits warnings for ESLint.
3
+ * @author Francesco Trotta
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //-----------------------------------------------------------------------------
9
+ // Exports
10
+ //-----------------------------------------------------------------------------
11
+
12
+ /**
13
+ * A service that emits warnings for ESLint.
14
+ */
15
+ class WarningService {
16
+ /**
17
+ * Creates a new instance of the service.
18
+ * @param {{ emitWarning?: ((warning: string, type: string) => void) | undefined }} [options] A function called internally to emit warnings using API provided by the runtime.
19
+ */
20
+ constructor({
21
+ emitWarning = globalThis.process?.emitWarning ?? (() => {}),
22
+ } = {}) {
23
+ this.emitWarning = emitWarning;
24
+ }
25
+
26
+ /**
27
+ * Emits a warning when circular fixes are detected while fixing a file.
28
+ * This method is used by the Linter and is safe to call outside Node.js.
29
+ * @param {string} filename The name of the file being fixed.
30
+ * @returns {void}
31
+ */
32
+ emitCircularFixesWarning(filename) {
33
+ this.emitWarning(
34
+ `Circular fixes detected while fixing ${filename}. It is likely that you have conflicting rules in your configuration.`,
35
+ "ESLintCircularFixesWarning",
36
+ );
37
+ }
38
+
39
+ /**
40
+ * Emits a warning when an empty config file has been loaded.
41
+ * @param {string} configFilePath The path to the config file.
42
+ * @returns {void}
43
+ */
44
+ emitEmptyConfigWarning(configFilePath) {
45
+ this.emitWarning(
46
+ `Running ESLint with an empty config (from ${configFilePath}). Please double-check that this is what you want. If you want to run ESLint with an empty config, export [{}] to remove this warning.`,
47
+ "ESLintEmptyConfigWarning",
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Emits a warning when an ".eslintignore" file is found.
53
+ * @returns {void}
54
+ */
55
+ emitESLintIgnoreWarning() {
56
+ this.emitWarning(
57
+ 'The ".eslintignore" file is no longer supported. Switch to using the "ignores" property in "eslint.config.js": https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files',
58
+ "ESLintIgnoreWarning",
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Emits a warning when the ESLINT_USE_FLAT_CONFIG environment variable is set to "false".
64
+ * @returns {void}
65
+ */
66
+ emitESLintRCWarning() {
67
+ this.emitWarning(
68
+ "You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.",
69
+ "ESLintRCWarning",
70
+ );
71
+ }
72
+
73
+ /**
74
+ * Emits a warning when an inactive flag is used.
75
+ * This method is used by the Linter and is safe to call outside Node.js.
76
+ * @param {string} flag The name of the flag.
77
+ * @param {string} message The warning message.
78
+ * @returns {void}
79
+ */
80
+ emitInactiveFlagWarning(flag, message) {
81
+ this.emitWarning(message, `ESLintInactiveFlag_${flag}`);
82
+ }
83
+ }
84
+
85
+ module.exports = { WarningService };
@@ -584,6 +584,11 @@ export namespace SourceCode {
584
584
 
585
585
  // #endregion
586
586
 
587
+ export type JSSyntaxElement = {
588
+ type: string;
589
+ loc?: ESTree.SourceLocation | null | undefined;
590
+ };
591
+
587
592
  export namespace Rule {
588
593
  interface RuleModule
589
594
  extends RuleDefinition<{
@@ -591,7 +596,7 @@ export namespace Rule {
591
596
  Code: SourceCode;
592
597
  RuleOptions: any[];
593
598
  Visitor: NodeListener;
594
- Node: ESTree.Node;
599
+ Node: JSSyntaxElement;
595
600
  MessageIds: string;
596
601
  ExtRuleDocs: {};
597
602
  }> {
@@ -1159,10 +1164,10 @@ export namespace Rule {
1159
1164
  /**
1160
1165
  * Indicates the type of rule:
1161
1166
  * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve.
1162
- * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isnt changed.
1167
+ * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn't changed.
1163
1168
  * - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses,
1164
1169
  * all the parts of the program that determine how the code looks rather than how it executes.
1165
- * These rules work on parts of the code that arent specified in the AST.
1170
+ * These rules work on parts of the code that aren't specified in the AST.
1166
1171
  */
1167
1172
  type?: "problem" | "suggestion" | "layout" | undefined;
1168
1173
  /**
@@ -1177,7 +1182,7 @@ export namespace Rule {
1177
1182
  LangOptions: Linter.LanguageOptions;
1178
1183
  Code: SourceCode;
1179
1184
  RuleOptions: any[];
1180
- Node: ESTree.Node;
1185
+ Node: JSSyntaxElement;
1181
1186
  MessageIds: string;
1182
1187
  }> {
1183
1188
  /*
@@ -1275,7 +1280,7 @@ export type JSRuleDefinition<
1275
1280
  LangOptions: Linter.LanguageOptions;
1276
1281
  Code: SourceCode;
1277
1282
  Visitor: Rule.NodeListener;
1278
- Node: ESTree.Node;
1283
+ Node: JSSyntaxElement;
1279
1284
  } & Required<
1280
1285
  // Rule specific type options (custom)
1281
1286
  Options &