Skip to content

Commit f5e23e2

Browse files
fix(utils): add defaultOptions to meta in rule (typescript-eslint#10339)
Co-authored-by: Brad Zacher <[email protected]>
1 parent 6ce04d5 commit f5e23e2

16 files changed

+68
-30
lines changed

packages/eslint-plugin/src/rules/consistent-return.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ type FunctionNode =
2121
| TSESTree.FunctionDeclaration
2222
| TSESTree.FunctionExpression;
2323

24+
const defaultOptions: Options = [{ treatUndefinedAsUnspecified: false }];
2425
export default createRule<Options, MessageIds>({
2526
name: 'consistent-return',
2627
meta: {
2728
type: 'suggestion',
29+
defaultOptions,
2830
docs: {
2931
description:
3032
'Require `return` statements to either always or never specify values',
@@ -35,7 +37,7 @@ export default createRule<Options, MessageIds>({
3537
messages: baseRule.meta.messages,
3638
schema: baseRule.meta.schema,
3739
},
38-
defaultOptions: [{ treatUndefinedAsUnspecified: false }],
40+
defaultOptions,
3941
create(context, [options]) {
4042
const services = getParserServices(context);
4143
const checker = services.program.getTypeChecker();

packages/eslint-plugin/src/rules/dot-notation.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,21 @@ const baseRule = getESLintCoreRule('dot-notation');
1717
export type Options = InferOptionsTypeFromRule<typeof baseRule>;
1818
export type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
1919

20+
const defaultOptions: Options = [
21+
{
22+
allowIndexSignaturePropertyAccess: false,
23+
allowKeywords: true,
24+
allowPattern: '',
25+
allowPrivateClassPropertyAccess: false,
26+
allowProtectedClassPropertyAccess: false,
27+
},
28+
];
29+
2030
export default createRule<Options, MessageIds>({
2131
name: 'dot-notation',
2232
meta: {
2333
type: 'suggestion',
34+
defaultOptions,
2435
docs: {
2536
description: 'Enforce dot notation whenever possible',
2637
extendsBaseRule: true,
@@ -67,15 +78,7 @@ export default createRule<Options, MessageIds>({
6778
},
6879
],
6980
},
70-
defaultOptions: [
71-
{
72-
allowIndexSignaturePropertyAccess: false,
73-
allowKeywords: true,
74-
allowPattern: '',
75-
allowPrivateClassPropertyAccess: false,
76-
allowProtectedClassPropertyAccess: false,
77-
},
78-
],
81+
defaultOptions,
7982
create(context, [options]) {
8083
const rules = baseRule.create(context);
8184
const services = getParserServices(context);

packages/eslint-plugin/src/rules/init-declarations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default createRule<Options, MessageIds>({
1919
name: 'init-declarations',
2020
meta: {
2121
type: 'suggestion',
22+
// defaultOptions, -- base rule does not use defaultOptions
2223
docs: {
2324
description:
2425
'Require or disallow initialization in variable declarations',

packages/eslint-plugin/src/rules/max-params.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default createRule<Options, MessageIds>({
2626
name: 'max-params',
2727
meta: {
2828
type: 'suggestion',
29+
// defaultOptions, -- base rule does not use defaultOptions
2930
docs: {
3031
description:
3132
'Enforce a maximum number of parameters in function definitions',

packages/eslint-plugin/src/rules/no-dupe-class-members.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default createRule<Options, MessageIds>({
1919
name: 'no-dupe-class-members',
2020
meta: {
2121
type: 'problem',
22+
// defaultOptions, -- base rule does not use defaultOptions
2223
docs: {
2324
description: 'Disallow duplicate class members',
2425
extendsBaseRule: true,

packages/eslint-plugin/src/rules/no-empty-function.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ const baseRule = getESLintCoreRule('no-empty-function');
1616
type Options = InferOptionsTypeFromRule<typeof baseRule>;
1717
type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
1818

19+
const defaultOptions: Options = [
20+
{
21+
allow: [],
22+
},
23+
];
24+
1925
const schema = deepMerge(
2026
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- https://github.com/microsoft/TypeScript/issues/17002
2127
Array.isArray(baseRule.meta.schema)
@@ -54,6 +60,7 @@ export default createRule<Options, MessageIds>({
5460
name: 'no-empty-function',
5561
meta: {
5662
type: 'suggestion',
63+
defaultOptions,
5764
docs: {
5865
description: 'Disallow empty functions',
5966
extendsBaseRule: true,
@@ -63,11 +70,7 @@ export default createRule<Options, MessageIds>({
6370
messages: baseRule.meta.messages,
6471
schema: [schema],
6572
},
66-
defaultOptions: [
67-
{
68-
allow: [],
69-
},
70-
],
73+
defaultOptions,
7174
create(context, [{ allow = [] }]) {
7275
const rules = baseRule.create(context);
7376

packages/eslint-plugin/src/rules/no-invalid-this.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ const baseRule = getESLintCoreRule('no-invalid-this');
1515
export type Options = InferOptionsTypeFromRule<typeof baseRule>;
1616
export type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
1717

18+
const defaultOptions: Options = [{ capIsConstructor: true }];
19+
1820
export default createRule<Options, MessageIds>({
1921
name: 'no-invalid-this',
2022
meta: {
2123
type: 'suggestion',
24+
defaultOptions,
2225
docs: {
2326
description:
2427
'Disallow `this` keywords outside of classes or class-like objects',
@@ -28,7 +31,7 @@ export default createRule<Options, MessageIds>({
2831
messages: baseRule.meta.messages,
2932
schema: baseRule.meta.schema,
3033
},
31-
defaultOptions: [{ capIsConstructor: true }],
34+
defaultOptions,
3235
create(context) {
3336
const rules = baseRule.create(context);
3437

packages/eslint-plugin/src/rules/no-loop-func.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default createRule<Options, MessageIds>({
1919
name: 'no-loop-func',
2020
meta: {
2121
type: 'suggestion',
22+
// defaultOptions, -- base rule does not use defaultOptions
2223
docs: {
2324
description:
2425
'Disallow function declarations that contain unsafe references inside loop statements',

packages/eslint-plugin/src/rules/no-loss-of-precision.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default createRule<Options, MessageIds>({
1515
name: 'no-loss-of-precision',
1616
meta: {
1717
type: 'problem',
18+
// defaultOptions, -- base rule does not use defaultOptions
1819
deprecated: true,
1920
docs: {
2021
description: 'Disallow literal numbers that lose precision',

packages/eslint-plugin/src/rules/no-magic-numbers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default createRule<Options, MessageIds>({
4949
name: 'no-magic-numbers',
5050
meta: {
5151
type: 'suggestion',
52+
// defaultOptions, -- base rule does not use defaultOptions
5253
docs: {
5354
description: 'Disallow magic numbers',
5455
extendsBaseRule: true,

packages/eslint-plugin/src/rules/no-restricted-imports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ export default createRule<Options, MessageIds>({
233233
name: 'no-restricted-imports',
234234
meta: {
235235
type: 'suggestion',
236+
// defaultOptions, -- base rule does not use defaultOptions
236237
docs: {
237238
description: 'Disallow specified modules when loaded by `import`',
238239
extendsBaseRule: true,

packages/eslint-plugin/src/rules/no-unused-expressions.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,19 @@ const baseRule = getESLintCoreRule('no-unused-expressions');
1313
type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;
1414
type Options = InferOptionsTypeFromRule<typeof baseRule>;
1515

16+
const defaultOptions: Options = [
17+
{
18+
allowShortCircuit: false,
19+
allowTaggedTemplates: false,
20+
allowTernary: false,
21+
},
22+
];
23+
1624
export default createRule<Options, MessageIds>({
1725
name: 'no-unused-expressions',
1826
meta: {
1927
type: 'suggestion',
28+
defaultOptions,
2029
docs: {
2130
description: 'Disallow unused expressions',
2231
extendsBaseRule: true,
@@ -26,13 +35,7 @@ export default createRule<Options, MessageIds>({
2635
messages: baseRule.meta.messages,
2736
schema: baseRule.meta.schema,
2837
},
29-
defaultOptions: [
30-
{
31-
allowShortCircuit: false,
32-
allowTaggedTemplates: false,
33-
allowTernary: false,
34-
},
35-
],
38+
defaultOptions,
3639
create(context, [{ allowShortCircuit = false, allowTernary = false }]) {
3740
const rules = baseRule.create(context);
3841

packages/eslint-plugin/src/rules/no-useless-constructor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export default createRule<Options, MessageIds>({
4747
name: 'no-useless-constructor',
4848
meta: {
4949
type: 'problem',
50+
// defaultOptions, -- base rule does not use defaultOptions
5051
docs: {
5152
description: 'Disallow unnecessary constructors',
5253
extendsBaseRule: true,

packages/eslint-plugin/src/rules/prefer-destructuring.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export default createRule<Options, MessageIds>({
7171
name: 'prefer-destructuring',
7272
meta: {
7373
type: 'suggestion',
74+
// defaultOptions, -- base rule does not use defaultOptions
7475
docs: {
7576
description: 'Require destructuring from arrays and/or objects',
7677
extendsBaseRule: true,

packages/utils/src/eslint-utils/RuleCreator.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ export type NamedCreateRuleMetaDocs = Omit<RuleMetaDataDocs, 'url'>;
1414
export type NamedCreateRuleMeta<
1515
MessageIds extends string,
1616
PluginDocs = unknown,
17+
Options extends readonly unknown[] = [],
1718
> = {
1819
docs: PluginDocs & RuleMetaDataDocs;
19-
} & Omit<RuleMetaData<MessageIds, PluginDocs>, 'docs'>;
20+
} & Omit<RuleMetaData<MessageIds, PluginDocs, Options>, 'docs'>;
2021

2122
export interface RuleCreateAndOptions<
2223
Options extends readonly unknown[],
@@ -34,15 +35,15 @@ export interface RuleWithMeta<
3435
MessageIds extends string,
3536
Docs = unknown,
3637
> extends RuleCreateAndOptions<Options, MessageIds> {
37-
meta: RuleMetaData<MessageIds, Docs>;
38+
meta: RuleMetaData<MessageIds, Docs, Options>;
3839
}
3940

4041
export interface RuleWithMetaAndName<
4142
Options extends readonly unknown[],
4243
MessageIds extends string,
4344
Docs = unknown,
4445
> extends RuleCreateAndOptions<Options, MessageIds> {
45-
meta: NamedCreateRuleMeta<MessageIds, Docs>;
46+
meta: NamedCreateRuleMeta<MessageIds, Docs, Options>;
4647
name: string;
4748
}
4849

packages/utils/src/ts-eslint/Rule.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ export interface RuleMetaDataDocs {
2727
url?: string;
2828
}
2929

30-
export interface RuleMetaData<MessageIds extends string, PluginDocs = unknown> {
30+
export interface RuleMetaData<
31+
MessageIds extends string,
32+
PluginDocs = unknown,
33+
Options extends readonly unknown[] = [],
34+
> {
3135
/**
3236
* True if the rule is deprecated, false otherwise
3337
*/
@@ -65,12 +69,22 @@ export interface RuleMetaData<MessageIds extends string, PluginDocs = unknown> {
6569
* - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren’t specified in the AST.
6670
*/
6771
type: 'layout' | 'problem' | 'suggestion';
72+
73+
/**
74+
* Specifies default options for the rule. If present, any user-provided options in their config will be merged on top of them recursively.
75+
* This merging will be applied directly to `context.options`.
76+
* If you want backwards-compatible support for earlier ESLint version; consider using the top-level `defaultOptions` instead.
77+
*
78+
* since ESLint 9.15.0
79+
*/
80+
defaultOptions?: Options;
6881
}
6982

7083
export interface RuleMetaDataWithDocs<
7184
MessageIds extends string,
7285
PluginDocs = unknown,
73-
> extends RuleMetaData<MessageIds, PluginDocs> {
86+
Options extends readonly unknown[] = [],
87+
> extends RuleMetaData<MessageIds, PluginDocs, Options> {
7488
/**
7589
* Documentation for the rule
7690
*/
@@ -655,7 +669,7 @@ export interface RuleModule<
655669
/**
656670
* Metadata about the rule
657671
*/
658-
meta: RuleMetaData<MessageIds, Docs>;
672+
meta: RuleMetaData<MessageIds, Docs, Options>;
659673
}
660674

661675
export type AnyRuleModule = RuleModule<string, readonly unknown[]>;
@@ -670,7 +684,7 @@ export interface RuleModuleWithMetaDocs<
670684
/**
671685
* Metadata about the rule
672686
*/
673-
meta: RuleMetaDataWithDocs<MessageIds, Docs>;
687+
meta: RuleMetaDataWithDocs<MessageIds, Docs, Options>;
674688
}
675689

676690
export type AnyRuleModuleWithMetaDocs = RuleModuleWithMetaDocs<

0 commit comments

Comments
 (0)