eslint 9.30.1 → 9.32.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.
@@ -1236,35 +1236,34 @@ class RuleTester {
1236
1236
  );
1237
1237
  }
1238
1238
 
1239
+ const actualLocation = {};
1240
+ const expectedLocation = {};
1241
+
1239
1242
  if (hasOwnProperty(error, "line")) {
1240
- assert.strictEqual(
1241
- message.line,
1242
- error.line,
1243
- `Error line should be ${error.line}`,
1244
- );
1243
+ actualLocation.line = message.line;
1244
+ expectedLocation.line = error.line;
1245
1245
  }
1246
1246
 
1247
1247
  if (hasOwnProperty(error, "column")) {
1248
- assert.strictEqual(
1249
- message.column,
1250
- error.column,
1251
- `Error column should be ${error.column}`,
1252
- );
1248
+ actualLocation.column = message.column;
1249
+ expectedLocation.column = error.column;
1253
1250
  }
1254
1251
 
1255
1252
  if (hasOwnProperty(error, "endLine")) {
1256
- assert.strictEqual(
1257
- message.endLine,
1258
- error.endLine,
1259
- `Error endLine should be ${error.endLine}`,
1260
- );
1253
+ actualLocation.endLine = message.endLine;
1254
+ expectedLocation.endLine = error.endLine;
1261
1255
  }
1262
1256
 
1263
1257
  if (hasOwnProperty(error, "endColumn")) {
1264
- assert.strictEqual(
1265
- message.endColumn,
1266
- error.endColumn,
1267
- `Error endColumn should be ${error.endColumn}`,
1258
+ actualLocation.endColumn = message.endColumn;
1259
+ expectedLocation.endColumn = error.endColumn;
1260
+ }
1261
+
1262
+ if (Object.keys(expectedLocation).length > 0) {
1263
+ assert.deepStrictEqual(
1264
+ actualLocation,
1265
+ expectedLocation,
1266
+ "Actual error location does not match expected error location.",
1268
1267
  );
1269
1268
  }
1270
1269
 
@@ -148,6 +148,7 @@ module.exports = {
148
148
 
149
149
  defaultOptions: [
150
150
  {
151
+ enforceForTSTypes: false,
151
152
  enforceForClassMembers: true,
152
153
  getWithoutSet: false,
153
154
  setWithoutGet: true,
@@ -174,6 +175,9 @@ module.exports = {
174
175
  enforceForClassMembers: {
175
176
  type: "boolean",
176
177
  },
178
+ enforceForTSTypes: {
179
+ type: "boolean",
180
+ },
177
181
  },
178
182
  additionalProperties: false,
179
183
  },
@@ -190,6 +194,8 @@ module.exports = {
190
194
  "Setter is not present for {{ name }}.",
191
195
  missingGetterInClass: "Getter is not present for class {{ name }}.",
192
196
  missingSetterInClass: "Setter is not present for class {{ name }}.",
197
+ missingGetterInType: "Getter is not present for type {{ name }}.",
198
+ missingSetterInType: "Setter is not present for type {{ name }}.",
193
199
  },
194
200
  },
195
201
  create(context) {
@@ -198,6 +204,7 @@ module.exports = {
198
204
  getWithoutSet: checkGetWithoutSet,
199
205
  setWithoutGet: checkSetWithoutGet,
200
206
  enforceForClassMembers,
207
+ enforceForTSTypes,
201
208
  },
202
209
  ] = context.options;
203
210
  const sourceCode = context.sourceCode;
@@ -228,6 +235,15 @@ module.exports = {
228
235
  name: astUtils.getFunctionNameWithKind(node.value),
229
236
  },
230
237
  });
238
+ } else if (node.type === "TSMethodSignature") {
239
+ context.report({
240
+ node,
241
+ messageId: `${messageKind}InType`,
242
+ loc: astUtils.getFunctionHeadLoc(node, sourceCode),
243
+ data: {
244
+ name: astUtils.getFunctionNameWithKind(node),
245
+ },
246
+ });
231
247
  } else {
232
248
  context.report({
233
249
  node,
@@ -371,6 +387,22 @@ module.exports = {
371
387
  checkList(methodDefinitions.filter(m => !m.static));
372
388
  }
373
389
 
390
+ /**
391
+ * Checks the given type.
392
+ * @param {ASTNode} node `TSTypeLiteral` or `TSInterfaceBody` node to check.
393
+ * @returns {void}
394
+ * @private
395
+ */
396
+ function checkType(node) {
397
+ const members =
398
+ node.type === "TSTypeLiteral" ? node.members : node.body;
399
+ const methodDefinitions = members.filter(
400
+ m => m.type === "TSMethodSignature",
401
+ );
402
+
403
+ checkList(methodDefinitions);
404
+ }
405
+
374
406
  const listeners = {};
375
407
 
376
408
  if (checkSetWithoutGet || checkGetWithoutSet) {
@@ -378,6 +410,9 @@ module.exports = {
378
410
  if (enforceForClassMembers) {
379
411
  listeners.ClassBody = checkClassBody;
380
412
  }
413
+ if (enforceForTSTypes) {
414
+ listeners["TSTypeLiteral, TSInterfaceBody"] = checkType;
415
+ }
381
416
  }
382
417
 
383
418
  return listeners;
@@ -87,6 +87,8 @@ function isAccessorKind(node) {
87
87
  return node.kind === "get" || node.kind === "set";
88
88
  }
89
89
 
90
+ const DEFAULT_ORDER = "anyOrder";
91
+
90
92
  //------------------------------------------------------------------------------
91
93
  // Rule Definition
92
94
  //------------------------------------------------------------------------------
@@ -96,7 +98,7 @@ module.exports = {
96
98
  meta: {
97
99
  type: "suggestion",
98
100
 
99
- defaultOptions: ["anyOrder"],
101
+ defaultOptions: [DEFAULT_ORDER],
100
102
 
101
103
  docs: {
102
104
  description:
@@ -106,8 +108,15 @@ module.exports = {
106
108
  },
107
109
 
108
110
  schema: [
111
+ { enum: ["anyOrder", "getBeforeSet", "setBeforeGet"] },
109
112
  {
110
- enum: ["anyOrder", "getBeforeSet", "setBeforeGet"],
113
+ type: "object",
114
+ properties: {
115
+ enforceForTSTypes: {
116
+ type: "boolean",
117
+ },
118
+ },
119
+ additionalProperties: false,
111
120
  },
112
121
  ],
113
122
 
@@ -120,7 +129,9 @@ module.exports = {
120
129
  },
121
130
 
122
131
  create(context) {
123
- const [order] = context.options;
132
+ const order = context.options[0] ?? DEFAULT_ORDER;
133
+ const enforceForTSTypes =
134
+ context.options[1]?.enforceForTSTypes ?? false;
124
135
  const sourceCode = context.sourceCode;
125
136
 
126
137
  /**
@@ -135,13 +146,22 @@ module.exports = {
135
146
  context.report({
136
147
  node: latterNode,
137
148
  messageId,
138
- loc: astUtils.getFunctionHeadLoc(latterNode.value, sourceCode),
149
+ loc: astUtils.getFunctionHeadLoc(
150
+ latterNode.type !== "TSMethodSignature"
151
+ ? latterNode.value
152
+ : latterNode,
153
+ sourceCode,
154
+ ),
139
155
  data: {
140
156
  formerName: astUtils.getFunctionNameWithKind(
141
- formerNode.value,
157
+ formerNode.type !== "TSMethodSignature"
158
+ ? formerNode.value
159
+ : formerNode,
142
160
  ),
143
161
  latterName: astUtils.getFunctionNameWithKind(
144
- latterNode.value,
162
+ latterNode.type !== "TSMethodSignature"
163
+ ? latterNode.value
164
+ : latterNode,
145
165
  ),
146
166
  },
147
167
  });
@@ -232,6 +252,16 @@ module.exports = {
232
252
  n => n.type === "MethodDefinition" && n.static,
233
253
  );
234
254
  },
255
+ "TSTypeLiteral, TSInterfaceBody"(node) {
256
+ if (enforceForTSTypes) {
257
+ checkList(
258
+ node.type === "TSTypeLiteral"
259
+ ? node.members
260
+ : node.body,
261
+ n => n.type === "TSMethodSignature",
262
+ );
263
+ }
264
+ },
235
265
  };
236
266
  },
237
267
  };
@@ -9,6 +9,8 @@
9
9
  // Helpers
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
13
+
12
14
  /**
13
15
  * Checks whether or not a given node is a for loop.
14
16
  * @param {ASTNode} block A node to check.
@@ -147,7 +149,7 @@ module.exports = {
147
149
  messageId = "initialized";
148
150
  } else if (
149
151
  mode === MODE_NEVER &&
150
- kind !== "const" &&
152
+ !CONSTANT_BINDINGS.has(kind) &&
151
153
  initialized &&
152
154
  !isIgnoredForLoop
153
155
  ) {
@@ -41,7 +41,10 @@ function isLooped(node, parent) {
41
41
 
42
42
  case "ForOfStatement":
43
43
  case "ForInStatement":
44
- return node === parent.body;
44
+ return (
45
+ node === parent.body ||
46
+ (node === parent.left && node.kind === "await using")
47
+ );
45
48
 
46
49
  case "WhileStatement":
47
50
  case "DoWhileStatement":
@@ -76,6 +79,13 @@ module.exports = {
76
79
  * @returns {void}
77
80
  */
78
81
  function validate(awaitNode) {
82
+ if (
83
+ awaitNode.type === "VariableDeclaration" &&
84
+ awaitNode.kind !== "await using"
85
+ ) {
86
+ return;
87
+ }
88
+
79
89
  if (awaitNode.type === "ForOfStatement" && !awaitNode.await) {
80
90
  return;
81
91
  }
@@ -99,6 +109,7 @@ module.exports = {
99
109
  return {
100
110
  AwaitExpression: validate,
101
111
  ForOfStatement: validate,
112
+ VariableDeclaration: validate,
102
113
  };
103
114
  },
104
115
  };
@@ -5,8 +5,18 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
8
12
  const astUtils = require("./utils/ast-utils");
9
13
 
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
19
+
10
20
  //------------------------------------------------------------------------------
11
21
  // Rule Definition
12
22
  //------------------------------------------------------------------------------
@@ -17,7 +27,8 @@ module.exports = {
17
27
  type: "problem",
18
28
 
19
29
  docs: {
20
- description: "Disallow reassigning `const` variables",
30
+ description:
31
+ "Disallow reassigning `const`, `using`, and `await using` variables",
21
32
  recommended: true,
22
33
  url: "https://eslint.org/docs/latest/rules/no-const-assign",
23
34
  },
@@ -51,7 +62,7 @@ module.exports = {
51
62
 
52
63
  return {
53
64
  VariableDeclaration(node) {
54
- if (node.kind === "const") {
65
+ if (CONSTANT_BINDINGS.has(node.kind)) {
55
66
  sourceCode
56
67
  .getDeclaredVariables(node)
57
68
  .forEach(checkVariable);
@@ -32,6 +32,7 @@ module.exports = {
32
32
  messages: {
33
33
  impliedEval:
34
34
  "Implied eval. Consider passing a function instead of a string.",
35
+ execScript: "Implied eval. Do not use execScript().",
35
36
  },
36
37
  },
37
38
 
@@ -85,9 +86,14 @@ module.exports = {
85
86
  isStaticString || isEvaluatedString(firstArgument);
86
87
 
87
88
  if (isString) {
89
+ const calleeName =
90
+ node.callee.type === "Identifier"
91
+ ? node.callee.name
92
+ : astUtils.getStaticPropertyName(node.callee);
93
+ const isExecScript = calleeName === "execScript";
88
94
  context.report({
89
95
  node,
90
- messageId: "impliedEval",
96
+ messageId: isExecScript ? "execScript" : "impliedEval",
91
97
  });
92
98
  }
93
99
  }
@@ -139,7 +145,11 @@ module.exports = {
139
145
  return {
140
146
  CallExpression(node) {
141
147
  if (
142
- astUtils.isSpecificId(node.callee, EVAL_LIKE_FUNC_PATTERN)
148
+ astUtils.isSpecificId(
149
+ node.callee,
150
+ EVAL_LIKE_FUNC_PATTERN,
151
+ ) &&
152
+ sourceCode.isGlobalReference(node.callee)
143
153
  ) {
144
154
  reportImpliedEvalCallExpression(node);
145
155
  }
@@ -9,6 +9,8 @@
9
9
  // Helpers
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
13
+
12
14
  /**
13
15
  * Identifies is a node is a FunctionExpression which is part of an IIFE
14
16
  * @param {ASTNode} node Node to test
@@ -148,8 +150,8 @@ module.exports = {
148
150
  ? declaration.kind
149
151
  : "";
150
152
 
151
- // Variables which are declared by `const` is safe.
152
- if (kind === "const") {
153
+ // Constant variables are safe.
154
+ if (CONSTANT_BINDINGS.has(kind)) {
153
155
  return true;
154
156
  }
155
157
 
@@ -5,8 +5,18 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
8
12
  const astUtils = require("./utils/ast-utils");
9
13
 
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
19
+
10
20
  //------------------------------------------------------------------------------
11
21
  // Rule Definition
12
22
  //------------------------------------------------------------------------------
@@ -49,7 +59,7 @@ module.exports = {
49
59
 
50
60
  if (
51
61
  init === "undefined" &&
52
- node.parent.kind !== "const" &&
62
+ !CONSTANT_BINDINGS.has(node.parent.kind) &&
53
63
  !shadowed
54
64
  ) {
55
65
  context.report({
@@ -88,6 +88,9 @@ module.exports = {
88
88
  ignoreClassWithStaticInitBlock: {
89
89
  type: "boolean",
90
90
  },
91
+ ignoreUsingDeclarations: {
92
+ type: "boolean",
93
+ },
91
94
  reportUsedIgnorePattern: {
92
95
  type: "boolean",
93
96
  },
@@ -119,6 +122,7 @@ module.exports = {
119
122
  ignoreRestSiblings: false,
120
123
  caughtErrors: "all",
121
124
  ignoreClassWithStaticInitBlock: false,
125
+ ignoreUsingDeclarations: false,
122
126
  reportUsedIgnorePattern: false,
123
127
  };
124
128
 
@@ -137,6 +141,9 @@ module.exports = {
137
141
  config.ignoreClassWithStaticInitBlock =
138
142
  firstOption.ignoreClassWithStaticInitBlock ||
139
143
  config.ignoreClassWithStaticInitBlock;
144
+ config.ignoreUsingDeclarations =
145
+ firstOption.ignoreUsingDeclarations ||
146
+ config.ignoreUsingDeclarations;
140
147
  config.reportUsedIgnorePattern =
141
148
  firstOption.reportUsedIgnorePattern ||
142
149
  config.reportUsedIgnorePattern;
@@ -357,6 +364,22 @@ module.exports = {
357
364
  return false;
358
365
  }
359
366
 
367
+ /**
368
+ * Determines if a given variable uses the explicit resource management protocol.
369
+ * @param {Variable} variable eslint-scope variable object.
370
+ * @returns {boolean} True if the variable is declared with "using" or "await using"
371
+ * @private
372
+ */
373
+ function usesExplicitResourceManagement(variable) {
374
+ const [definition] = variable.defs;
375
+
376
+ return (
377
+ definition?.type === "Variable" &&
378
+ (definition.parent.kind === "using" ||
379
+ definition.parent.kind === "await using")
380
+ );
381
+ }
382
+
360
383
  /**
361
384
  * Checks whether a node is a sibling of the rest property or not.
362
385
  * @param {ASTNode} node a node to check
@@ -922,6 +945,10 @@ module.exports = {
922
945
  if (
923
946
  !isUsedVariable(variable) &&
924
947
  !isExported(variable) &&
948
+ !(
949
+ config.ignoreUsingDeclarations &&
950
+ usesExplicitResourceManagement(variable)
951
+ ) &&
925
952
  !hasRestSpreadSibling(variable)
926
953
  ) {
927
954
  unusedVars.push(variable);
@@ -293,6 +293,14 @@ module.exports = {
293
293
  return;
294
294
  }
295
295
 
296
+ // Variable declarations using explicit resource management cannot use destructuring (parse error)
297
+ if (
298
+ node.parent.kind === "using" ||
299
+ node.parent.kind === "await using"
300
+ ) {
301
+ return;
302
+ }
303
+
296
304
  // We only care about member expressions past this point
297
305
  if (node.init.type !== "MemberExpression") {
298
306
  return;
@@ -170,6 +170,15 @@ module.exports = {
170
170
  scopeInfo.hasAwait = true;
171
171
  }
172
172
  },
173
+ VariableDeclaration(node) {
174
+ if (!scopeInfo) {
175
+ return;
176
+ }
177
+
178
+ if (node.kind === "await using") {
179
+ scopeInfo.hasAwait = true;
180
+ }
181
+ },
173
182
  };
174
183
  },
175
184
  };
@@ -47,6 +47,12 @@ const STATEMENT_LIST_PARENTS = new Set([
47
47
  "StaticBlock",
48
48
  "SwitchCase",
49
49
  ]);
50
+ const LEXICAL_DECLARATION_KINDS = new Set([
51
+ "let",
52
+ "const",
53
+ "using",
54
+ "await using",
55
+ ]);
50
56
 
51
57
  const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;
52
58
 
@@ -298,6 +304,8 @@ function getStaticPropertyName(node) {
298
304
  case "Property":
299
305
  case "PropertyDefinition":
300
306
  case "MethodDefinition":
307
+ case "TSPropertySignature":
308
+ case "TSMethodSignature":
301
309
  prop = node.key;
302
310
  break;
303
311
 
@@ -1989,13 +1997,15 @@ module.exports = {
1989
1997
 
1990
1998
  if (
1991
1999
  parent.type === "MethodDefinition" ||
1992
- parent.type === "PropertyDefinition"
2000
+ parent.type === "PropertyDefinition" ||
2001
+ node.type === "TSPropertySignature" ||
2002
+ node.type === "TSMethodSignature"
1993
2003
  ) {
1994
2004
  // The proposal uses `static` word consistently before visibility words: https://github.com/tc39/proposal-static-class-features
1995
2005
  if (parent.static) {
1996
2006
  tokens.push("static");
1997
2007
  }
1998
- if (!parent.computed && parent.key.type === "PrivateIdentifier") {
2008
+ if (!parent.computed && parent.key?.type === "PrivateIdentifier") {
1999
2009
  tokens.push("private");
2000
2010
  }
2001
2011
  }
@@ -2017,6 +2027,14 @@ module.exports = {
2017
2027
  } else {
2018
2028
  tokens.push("method");
2019
2029
  }
2030
+ } else if (node.type === "TSMethodSignature") {
2031
+ if (node.kind === "get") {
2032
+ tokens.push("getter");
2033
+ } else if (node.kind === "set") {
2034
+ tokens.push("setter");
2035
+ } else {
2036
+ tokens.push("method");
2037
+ }
2020
2038
  } else if (parent.type === "PropertyDefinition") {
2021
2039
  tokens.push("method");
2022
2040
  } else {
@@ -2042,6 +2060,8 @@ module.exports = {
2042
2060
  tokens.push(`'${node.id.name}'`);
2043
2061
  }
2044
2062
  }
2063
+ } else if (node.type === "TSMethodSignature") {
2064
+ tokens.push(`'${getStaticPropertyName(node)}'`);
2045
2065
  } else if (node.id) {
2046
2066
  tokens.push(`'${node.id.name}'`);
2047
2067
  }
@@ -2154,7 +2174,9 @@ module.exports = {
2154
2174
  if (
2155
2175
  parent.type === "Property" ||
2156
2176
  parent.type === "MethodDefinition" ||
2157
- parent.type === "PropertyDefinition"
2177
+ parent.type === "PropertyDefinition" ||
2178
+ parent.type === "TSPropertySignature" ||
2179
+ parent.type === "TSMethodSignature"
2158
2180
  ) {
2159
2181
  start = parent.loc.start;
2160
2182
  end = getOpeningParenOfParams(node, sourceCode).loc.start;
@@ -2573,16 +2595,14 @@ module.exports = {
2573
2595
  */
2574
2596
  areBracesNecessary(node, sourceCode) {
2575
2597
  /**
2576
- * Determines if the given node is a lexical declaration (let, const, function, or class)
2598
+ * Determines if the given node is a lexical declaration (let, const, using, await using, function, or class)
2577
2599
  * @param {ASTNode} nodeToCheck The node to check
2578
2600
  * @returns {boolean} True if the node is a lexical declaration
2579
2601
  * @private
2580
2602
  */
2581
2603
  function isLexicalDeclaration(nodeToCheck) {
2582
2604
  if (nodeToCheck.type === "VariableDeclaration") {
2583
- return (
2584
- nodeToCheck.kind === "const" || nodeToCheck.kind === "let"
2585
- );
2605
+ return LEXICAL_DECLARATION_KINDS.has(nodeToCheck.kind);
2586
2606
  }
2587
2607
 
2588
2608
  return (
@@ -27,15 +27,17 @@
27
27
 
28
28
  import * as ESTree from "estree";
29
29
  import type {
30
- RuleVisitor,
31
- TextSourceCode,
30
+ CustomRuleDefinitionType,
31
+ CustomRuleTypeDefinitions,
32
+ DeprecatedInfo,
32
33
  Language,
33
- SourceRange,
34
- TraversalStep,
35
34
  LanguageOptions as GenericLanguageOptions,
36
- RuleDefinition,
37
35
  RuleContext as CoreRuleContext,
38
- DeprecatedInfo,
36
+ RuleDefinition,
37
+ RuleVisitor,
38
+ SourceRange,
39
+ TextSourceCode,
40
+ TraversalStep,
39
41
  } from "@eslint/core";
40
42
  import { JSONSchema4 } from "json-schema";
41
43
  import { LegacyESLint } from "./use-at-your-own-risk.js";
@@ -1186,25 +1188,7 @@ export namespace Rule {
1186
1188
  RuleOptions: any[];
1187
1189
  Node: JSSyntaxElement;
1188
1190
  MessageIds: string;
1189
- }> {
1190
- /*
1191
- * Need to extend the `RuleContext` interface to include the
1192
- * deprecated methods that have not yet been removed.
1193
- * TODO: Remove in v10.0.0.
1194
- */
1195
-
1196
- /** @deprecated Use `sourceCode.getAncestors()` instead */
1197
- getAncestors(): ESTree.Node[];
1198
-
1199
- /** @deprecated Use `sourceCode.getDeclaredVariables()` instead */
1200
- getDeclaredVariables(node: ESTree.Node): Scope.Variable[];
1201
-
1202
- /** @deprecated Use `sourceCode.getScope()` instead */
1203
- getScope(): Scope.Scope;
1204
-
1205
- /** @deprecated Use `sourceCode.markVariableAsUsed()` instead */
1206
- markVariableAsUsed(name: string): boolean;
1207
- }
1191
+ }> {}
1208
1192
 
1209
1193
  type ReportFixer = (
1210
1194
  fixer: RuleFixer,
@@ -1268,27 +1252,18 @@ export namespace Rule {
1268
1252
  }
1269
1253
  }
1270
1254
 
1271
- export type JSRuleDefinitionTypeOptions = {
1272
- RuleOptions: unknown[];
1273
- MessageIds: string;
1274
- ExtRuleDocs: Record<string, unknown>;
1275
- };
1255
+ export type JSRuleDefinitionTypeOptions = CustomRuleTypeDefinitions;
1276
1256
 
1277
1257
  export type JSRuleDefinition<
1278
1258
  Options extends Partial<JSRuleDefinitionTypeOptions> = {},
1279
- > = RuleDefinition<
1280
- // Language specific type options (non-configurable)
1259
+ > = CustomRuleDefinitionType<
1281
1260
  {
1282
1261
  LangOptions: Linter.LanguageOptions;
1283
1262
  Code: SourceCode;
1284
1263
  Visitor: Rule.NodeListener;
1285
1264
  Node: JSSyntaxElement;
1286
- } & Required<
1287
- // Rule specific type options (custom)
1288
- Options &
1289
- // Rule specific type options (defaults)
1290
- Omit<JSRuleDefinitionTypeOptions, keyof Options>
1291
- >
1265
+ },
1266
+ Options
1292
1267
  >;
1293
1268
 
1294
1269
  // #region Linter
@@ -1615,7 +1590,6 @@ export namespace Linter {
1615
1590
  globalReturn?: boolean | undefined;
1616
1591
  impliedStrict?: boolean | undefined;
1617
1592
  jsx?: boolean | undefined;
1618
- experimentalObjectRestSpread?: boolean | undefined;
1619
1593
  [key: string]: any;
1620
1594
  }
1621
1595
  | undefined;