Skip to content

Commit 86fa76a

Browse files
committedAug 5, 2024··
feat(prefer-immutable-types): allow overriding options based on where the type is declared (#804)
fix #800
1 parent b3cb8d9 commit 86fa76a

File tree

3 files changed

+332
-193
lines changed

3 files changed

+332
-193
lines changed
 

‎docs/rules/prefer-immutable-types.md

+57
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,37 @@ type Options = {
255255
Array<{ pattern: string; replace: string; message?: string }>
256256
>;
257257
};
258+
259+
overrides?: Array<{
260+
match: Array<
261+
| {
262+
from: "file";
263+
path?: string;
264+
name?: string | string[];
265+
pattern?: RegExp | RegExp[];
266+
ignoreName?: string | string[];
267+
ignorePattern?: RegExp | RegExp[];
268+
}
269+
| {
270+
from: "lib";
271+
name?: string | string[];
272+
pattern?: RegExp | RegExp[];
273+
ignoreName?: string | string[];
274+
ignorePattern?: RegExp | RegExp[];
275+
}
276+
| {
277+
from: "package";
278+
package?: string;
279+
name?: string | string[];
280+
pattern?: RegExp | RegExp[];
281+
ignoreName?: string | string[];
282+
ignorePattern?: RegExp | RegExp[];
283+
}
284+
>;
285+
options: Omit<Options, "overrides">;
286+
inherit?: boolean;
287+
disable: boolean;
288+
}>;
258289
};
259290
```
260291

@@ -488,3 +519,29 @@ It allows for the ability to ignore violations based on the identifier (name) of
488519

489520
This option takes a `RegExp` string or an array of `RegExp` strings.
490521
It allows for the ability to ignore violations based on the type (as written, with whitespace removed) of the node in question.
522+
523+
### `overrides`
524+
525+
Allows for applying overrides to the options based on the type's declaration.
526+
This can be used to override the settings for types coming from 3rd party libraries.
527+
528+
Note: Only the first matching override will be used.
529+
530+
#### `overrides[n].specifiers`
531+
532+
A specifier, or an array of specifiers to match the function type against.
533+
534+
In the case of reference types, both the type and its generics will be recursively checked.
535+
If any of them match, the specifier will be considered a match.
536+
537+
#### `overrides[n].options`
538+
539+
The options to use when a specifiers matches.
540+
541+
#### `overrides[n].inherit`
542+
543+
Inherit the root options? Default is `true`.
544+
545+
#### `overrides[n].disable`
546+
547+
If true, when a specifier matches, this rule will not be applied to the matching node.

‎eslint.config.js

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export default rsEslint(
5252
"ts/no-unnecessary-condition": "off",
5353

5454
// Temp
55-
"functional/prefer-immutable-types": "off",
5655
"functional/no-throw-statements": "off",
5756
},
5857
},

‎src/rules/prefer-immutable-types.ts

+275-192
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@
99
} from "@typescript-eslint/utils/ts-eslint";
1010
import { deepmerge } from "deepmerge-ts";
1111
import { Immutability } from "is-immutable-type";
12+
import type { Type, TypeNode } from "typescript";
1213

1314
import {
1415
type IgnoreClassesOption,
16+
type OverridableOptions,
17+
type RawOverridableOptions,
18+
getCoreOptions,
19+
getCoreOptionsForType,
1520
ignoreClassesOptionSchema,
1621
shouldIgnoreClasses,
1722
shouldIgnoreInFunction,
1823
shouldIgnorePattern,
24+
upgradeRawOverridableOptions,
1925
} from "#/options";
2026
import { ruleNameScope } from "#/utils/misc";
2127
import type { ESFunctionType } from "#/utils/node-types";
@@ -25,6 +31,7 @@
2531
type RuleResult,
2632
createRule,
2733
getReturnTypesOfFunction,
34+
getTypeDataOfNode,
2835
getTypeImmutabilityOfNode,
2936
getTypeImmutabilityOfType,
3037
isImplementationOfOverload,
@@ -43,6 +50,8 @@
4350
isTSTypePredicate,
4451
} from "#/utils/type-guards";
4552

53+
import { overridableOptionsSchema } from "../utils/schemas";
54+
4655
/**
4756
* The name of this rule.
4857
*/
@@ -56,7 +65,8 @@
5665
type RawEnforcement =
5766
| Exclude<Immutability | keyof typeof Immutability, "Unknown" | "Mutable">
5867
| "None"
59-
| false;
68+
| false
69+
| undefined;
6070

6171
type Option = IgnoreClassesOption & {
6272
enforcement: RawEnforcement;
@@ -65,6 +75,20 @@
6575
ignoreTypePattern?: string[] | string;
6676
};
6777

78+
type CoreOptions = Option & {
79+
parameters?: Partial<Option> | RawEnforcement;
80+
returnTypes?: Partial<Option> | RawEnforcement;
81+
variables?:
82+
| Partial<
83+
Option & {
84+
ignoreInFunctions?: boolean;
85+
}
86+
>
87+
| RawEnforcement;
88+
fixer?: FixerConfigRawMap;
89+
suggestions?: SuggestionConfigRawMap;
90+
};
91+
6892
type FixerConfigRaw = {
6993
pattern: string;
7094
replace: string;
@@ -96,21 +120,8 @@
96120
/**
97121
* The options this rule can take.
98122
*/
99-
type Options = [
100-
Option & {
101-
parameters?: Partial<Option> | RawEnforcement;
102-
returnTypes?: Partial<Option> | RawEnforcement;
103-
variables?:
104-
| Partial<
105-
Option & {
106-
ignoreInFunctions?: boolean;
107-
}
108-
>
109-
| RawEnforcement;
110-
fixer?: FixerConfigRawMap;
111-
suggestions?: SuggestionConfigRawMap;
112-
},
113-
];
123+
type RawOptions = [RawOverridableOptions<CoreOptions>];
124+
type Options = OverridableOptions<CoreOptions>;
114125

115126
/**
116127
* The enum options for the level of enforcement.
@@ -215,59 +226,59 @@
215226
},
216227
};
217228

218-
/**
219-
* The schema for the rule options.
220-
*/
221-
const schema: JSONSchema4[] = [
222-
{
223-
type: "object",
224-
properties: deepmerge(optionExpandedSchema, {
225-
parameters: optionSchema,
226-
returnTypes: optionSchema,
227-
variables: {
228-
oneOf: [
229-
{
230-
type: "object",
231-
properties: deepmerge(optionExpandedSchema, {
232-
ignoreInFunctions: {
233-
type: "boolean",
234-
},
235-
} satisfies JSONSchema4ObjectSchema["properties"]),
236-
additionalProperties: false,
237-
},
238-
{
239-
type: ["string", "number", "boolean"],
240-
enum: enforcementEnumOptions,
241-
},
242-
],
243-
},
244-
fixer: {
229+
const coreOptionsPropertiesSchema: NonNullable<
230+
JSONSchema4ObjectSchema["properties"]
231+
> = deepmerge(optionExpandedSchema, {
232+
parameters: optionSchema,
233+
returnTypes: optionSchema,
234+
variables: {
235+
oneOf: [
236+
{
245237
type: "object",
246-
properties: {
247-
ReadonlyShallow: fixerSchema,
248-
ReadonlyDeep: fixerSchema,
249-
Immutable: fixerSchema,
250-
},
238+
properties: deepmerge(optionExpandedSchema, {
239+
ignoreInFunctions: {
240+
type: "boolean",
241+
},
242+
} satisfies JSONSchema4ObjectSchema["properties"]),
251243
additionalProperties: false,
252244
},
253-
suggestions: {
254-
type: "object",
255-
properties: {
256-
ReadonlyShallow: suggestionsSchema,
257-
ReadonlyDeep: suggestionsSchema,
258-
Immutable: suggestionsSchema,
259-
},
260-
additionalProperties: false,
245+
{
246+
type: ["string", "number", "boolean"],
247+
enum: enforcementEnumOptions,
261248
},
262-
} satisfies JSONSchema4ObjectSchema["properties"]),
249+
],
250+
},
251+
fixer: {
252+
type: "object",
253+
properties: {
254+
ReadonlyShallow: fixerSchema,
255+
ReadonlyDeep: fixerSchema,
256+
Immutable: fixerSchema,
257+
},
263258
additionalProperties: false,
264259
},
260+
suggestions: {
261+
type: "object",
262+
properties: {
263+
ReadonlyShallow: suggestionsSchema,
264+
ReadonlyDeep: suggestionsSchema,
265+
Immutable: suggestionsSchema,
266+
},
267+
additionalProperties: false,
268+
},
269+
} satisfies JSONSchema4ObjectSchema["properties"]);
270+
271+
/**
272+
* The schema for the rule options.
273+
*/
274+
const schema: JSONSchema4[] = [
275+
overridableOptionsSchema(coreOptionsPropertiesSchema),
265276
];
266277

267278
/**
268279
* The default options for the rule.
269280
*/
270-
const defaultOptions: Options = [
281+
const defaultOptions: RawOptions = [
271282
{
272283
enforcement: Immutability.Immutable,
273284
ignoreInferredTypes: false,
@@ -337,7 +348,7 @@
337348

338349
type Descriptor = RuleResult<
339350
keyof typeof errorMessages,
340-
Options
351+
RawOptions
341352
>["descriptors"][number];
342353

343354
type AllFixers = {
@@ -350,7 +361,7 @@
350361
*/
351362
function getAllFixers(
352363
node: TSESTree.Node,
353-
context: Readonly<RuleContext<keyof typeof errorMessages, Options>>,
364+
context: Readonly<RuleContext<keyof typeof errorMessages, RawOptions>>,
354365
fixerConfigs: FixerConfig[] | false,
355366
suggestionsConfigs: SuggestionsConfig[] | false,
356367
): AllFixers {
@@ -422,7 +433,7 @@
422433
* Get the level of enforcement from the raw value given.
423434
*/
424435
function parseEnforcement(rawEnforcement: RawEnforcement) {
425-
return rawEnforcement === "None"
436+
return rawEnforcement === "None" || rawEnforcement === undefined
426437
? false
427438
: typeof rawEnforcement === "string"
428439
? Immutability[rawEnforcement]
@@ -433,7 +444,7 @@
433444
* Get the fixer config for the the given enforcement level from the raw config given.
434445
*/
435446
function parseFixerConfigs(
436-
allRawConfigs: Options[0]["fixer"],
447+
allRawConfigs: RawOptions[0]["fixer"],
437448
enforcement: Immutability,
438449
): FixerConfig[] | false {
439450
const key = Immutability[enforcement] as keyof NonNullable<
@@ -454,7 +465,7 @@
454465
* Get the suggestions config for the the given enforcement level from the raw config given.
455466
*/
456467
function parseSuggestionsConfigs(
457-
rawSuggestions: Options[0]["suggestions"],
468+
rawSuggestions: RawOptions[0]["suggestions"],
458469
enforcement: Immutability,
459470
): SuggestionsConfig[] | false {
460471
const key = Immutability[enforcement] as keyof NonNullable<
@@ -477,56 +488,67 @@
477488
*/
478489
function getParameterTypeViolations(
479490
node: ESFunctionType,
480-
context: Readonly<RuleContext<keyof typeof errorMessages, Options>>,
491+
context: Readonly<RuleContext<keyof typeof errorMessages, RawOptions>>,
481492
options: Readonly<Options>,
482493
): Descriptor[] {
483-
const [optionsObject] = options;
484-
const {
485-
parameters: rawOption,
486-
fixer: rawFixerConfig,
487-
suggestions: rawSuggestionsConfigs,
488-
} = optionsObject;
489-
const {
490-
enforcement: rawEnforcement,
491-
ignoreInferredTypes,
492-
ignoreClasses,
493-
ignoreNamePattern,
494-
ignoreTypePattern,
495-
} = {
496-
ignoreInferredTypes: optionsObject.ignoreInferredTypes,
497-
ignoreClasses: optionsObject.ignoreClasses,
498-
ignoreNamePattern: optionsObject.ignoreNamePattern,
499-
ignoreTypePattern: optionsObject.ignoreTypePattern,
500-
...(typeof rawOption === "object"
501-
? rawOption
502-
: {
503-
enforcement: rawOption,
504-
}),
505-
};
494+
return node.params
495+
.map((param): Descriptor | undefined => {
496+
const parameterProperty = isTSParameterProperty(param);
497+
const actualParam = parameterProperty ? param.parameter : param;
506498

507-
const enforcement = parseEnforcement(
508-
rawEnforcement ?? optionsObject.enforcement,
509-
);
510-
if (
511-
enforcement === false ||
512-
shouldIgnoreClasses(node, context, ignoreClasses)
513-
) {
514-
return [];
515-
}
499+
const optionsToUse = getCoreOptions<CoreOptions, Options>(
500+
param,
501+
context,
502+
options,
503+
);
516504

517-
const fixerConfigs = parseFixerConfigs(rawFixerConfig, enforcement);
518-
const suggestionsConfigs = parseSuggestionsConfigs(
519-
rawSuggestionsConfigs,
520-
enforcement,
521-
);
505+
if (optionsToUse === null) {
506+
return undefined;
507+
}
508+
509+
const {
510+
parameters: rawOption,
511+
fixer: rawFixerConfig,
512+
suggestions: rawSuggestionsConfigs,
513+
} = optionsToUse;
514+
const {
515+
enforcement: rawEnforcement,
516+
ignoreInferredTypes,
517+
ignoreClasses,
518+
ignoreNamePattern,
519+
ignoreTypePattern,
520+
} = {
521+
ignoreInferredTypes: optionsToUse.ignoreInferredTypes,
522+
ignoreClasses: optionsToUse.ignoreClasses,
523+
ignoreNamePattern: optionsToUse.ignoreNamePattern,
524+
ignoreTypePattern: optionsToUse.ignoreTypePattern,
525+
...(typeof rawOption === "object"
526+
? rawOption
527+
: {
528+
enforcement: rawOption,
529+
}),
530+
};
531+
532+
const enforcement = parseEnforcement(
533+
rawEnforcement ?? optionsToUse.enforcement,
534+
);
535+
if (
536+
enforcement === false ||
537+
shouldIgnoreClasses(node, context, ignoreClasses)
538+
) {
539+
return undefined;
540+
}
541+
542+
const fixerConfigs = parseFixerConfigs(rawFixerConfig, enforcement);
543+
const suggestionsConfigs = parseSuggestionsConfigs(
544+
rawSuggestionsConfigs,
545+
enforcement,
546+
);
522547

523-
return node.params
524-
.map((param): Descriptor | undefined => {
525548
if (shouldIgnorePattern(param, context, ignoreNamePattern)) {
526549
return undefined;
527550
}
528551

529-
const parameterProperty = isTSParameterProperty(param);
530552
if (parameterProperty && !param.readonly) {
531553
const fix: NonNullable<Descriptor["fix"]> | null = (fixer) =>
532554
fixer.insertTextBefore(param.parameter, "readonly ");
@@ -544,8 +566,6 @@
544566
};
545567
}
546568

547-
const actualParam = parameterProperty ? param.parameter : param;
548-
549569
if (
550570
// inferred types
551571
(ignoreInferredTypes && actualParam.typeAnnotation === undefined) ||
@@ -596,7 +616,7 @@
596616
},
597617
fix,
598618
suggest:
599619
suggestionFixers?.map(({ fix, message }) => ({
600620
messageId: "userDefined",
601621
data: {
602622
message,
@@ -613,92 +633,124 @@
613633
*/
614634
function getReturnTypeViolations(
615635
node: ESFunctionType,
616-
context: Readonly<RuleContext<keyof typeof errorMessages, Options>>,
636+
context: Readonly<RuleContext<keyof typeof errorMessages, RawOptions>>,
617637
options: Readonly<Options>,
618638
): Descriptor[] {
619-
const [optionsObject] = options;
620-
const {
621-
returnTypes: rawOption,
622-
fixer: rawFixerConfig,
623-
suggestions: rawSuggestionsConfigs,
624-
} = optionsObject;
625-
const {
626-
enforcement: rawEnforcement,
627-
ignoreInferredTypes,
628-
ignoreClasses,
629-
ignoreNamePattern,
630-
ignoreTypePattern,
631-
} = {
632-
ignoreInferredTypes: optionsObject.ignoreInferredTypes,
633-
ignoreClasses: optionsObject.ignoreClasses,
634-
ignoreNamePattern: optionsObject.ignoreNamePattern,
635-
ignoreTypePattern: optionsObject.ignoreTypePattern,
636-
...(typeof rawOption === "object" ? rawOption : { enforcement: rawOption }),
637-
};
639+
function getOptions(type: Type, typeNode: TypeNode | null) {
640+
const optionsToUse = getCoreOptionsForType<CoreOptions, Options>(
641+
type,
642+
typeNode,
643+
context,
644+
options,
645+
);
638646

639-
const enforcement = parseEnforcement(
640-
rawEnforcement ?? optionsObject.enforcement,
641-
);
647+
if (optionsToUse === null) {
648+
return null;
649+
}
642650

643-
if (
644-
enforcement === false ||
645-
(ignoreInferredTypes && node.returnType?.typeAnnotation === undefined) ||
646-
shouldIgnoreClasses(node, context, ignoreClasses) ||
647-
shouldIgnorePattern(node, context, ignoreNamePattern)
648-
) {
649-
return [];
650-
}
651+
const {
652+
returnTypes: rawOption,
653+
fixer: rawFixerConfig,
654+
suggestions: rawSuggestionsConfigs,
655+
} = optionsToUse;
656+
const {
657+
enforcement: rawEnforcement,
658+
ignoreClasses,
659+
ignoreNamePattern,
660+
ignoreTypePattern,
661+
ignoreInferredTypes,
662+
} = {
663+
ignoreClasses: optionsToUse.ignoreClasses,
664+
ignoreNamePattern: optionsToUse.ignoreNamePattern,
665+
ignoreTypePattern: optionsToUse.ignoreTypePattern,
666+
ignoreInferredTypes: optionsToUse.ignoreInferredTypes,
667+
...(typeof rawOption === "object"
668+
? rawOption
669+
: { enforcement: rawOption }),
670+
};
651671

652-
const fixerConfigs = parseFixerConfigs(rawFixerConfig, enforcement);
653-
const suggestionsConfigs = parseSuggestionsConfigs(
654-
rawSuggestionsConfigs,
655-
enforcement,
656-
);
672+
const enforcement = parseEnforcement(
673+
rawEnforcement ?? optionsToUse.enforcement,
674+
);
657675

658-
if (
659-
node.returnType?.typeAnnotation !== undefined &&
660-
!isTSTypePredicate(node.returnType.typeAnnotation)
661-
) {
662-
if (shouldIgnorePattern(node.returnType, context, ignoreTypePattern)) {
663-
return [];
676+
if (
677+
enforcement === false ||
678+
shouldIgnoreClasses(node, context, ignoreClasses) ||
679+
shouldIgnorePattern(node, context, ignoreNamePattern)
680+
) {
681+
return null;
664682
}
665683

666-
const immutability = getTypeImmutabilityOfNode(
667-
node.returnType.typeAnnotation,
668-
context,
684+
const fixerConfigs = parseFixerConfigs(rawFixerConfig, enforcement);
685+
const suggestionsConfigs = parseSuggestionsConfigs(
686+
rawSuggestionsConfigs,
669687
enforcement,
670688
);
671689

672-
if (immutability >= enforcement) {
690+
return {
691+
ignoreTypePattern,
692+
ignoreInferredTypes,
693+
enforcement,
694+
fixerConfigs,
695+
suggestionsConfigs,
696+
};
697+
}
698+
699+
if (node.returnType?.typeAnnotation !== undefined) {
700+
const [type, typeNode] = getTypeDataOfNode(node, context);
701+
const optionsToUse = getOptions(type, typeNode);
702+
if (optionsToUse === null) {
673703
return [];
674704
}
675705

676-
const { fix, suggestionFixers } = getAllFixers(
677-
node.returnType.typeAnnotation,
678-
context,
679-
fixerConfigs,
680-
suggestionsConfigs,
681-
);
706+
const { ignoreTypePattern, enforcement, fixerConfigs, suggestionsConfigs } =
707+
optionsToUse;
682708

683-
return [
684-
{
685-
node: node.returnType,
686-
messageId: "returnType",
687-
data: {
688-
actual: Immutability[immutability],
689-
expected: Immutability[enforcement],
709+
if (
710+
node.returnType?.typeAnnotation !== undefined &&
711+
!isTSTypePredicate(node.returnType.typeAnnotation)
712+
) {
713+
if (shouldIgnorePattern(node.returnType, context, ignoreTypePattern)) {
714+
return [];
715+
}
716+
717+
const immutability = getTypeImmutabilityOfNode(
718+
node.returnType.typeAnnotation,
719+
context,
720+
enforcement,
721+
);
722+
723+
if (immutability >= enforcement) {
724+
return [];
725+
}
726+
727+
const { fix, suggestionFixers } = getAllFixers(
728+
node.returnType.typeAnnotation,
729+
context,
730+
fixerConfigs,
731+
suggestionsConfigs,
732+
);
733+
734+
return [
735+
{
736+
node: node.returnType,
737+
messageId: "returnType",
738+
data: {
739+
actual: Immutability[immutability],
740+
expected: Immutability[enforcement],
741+
},
742+
fix,
743+
suggest:
744+
suggestionFixers?.map(({ fix, message }) => ({
745+
messageId: "userDefined",
746+
data: {
747+
message,
748+
},
749+
fix,
750+
})) ?? null,
690751
},
691-
fix,
692-
suggest:
693-
suggestionFixers?.map(({ fix, message }) => ({
694-
messageId: "userDefined",
695-
data: {
696-
message,
697-
},
698-
fix,
699-
})) ?? null,
700-
},
701-
];
752+
];
753+
}
702754
}
703755

704756
if (!isFunctionLike(node)) {
@@ -714,8 +766,25 @@
714766
return [];
715767
}
716768

769+
const returnType = returnTypes[0]!;
770+
771+
const optionsToUse = getOptions(
772+
returnType,
773+
(returnType as Type & { node: TypeNode }).node ?? null,
774+
);
775+
if (optionsToUse === null) {
776+
return [];
777+
}
778+
779+
const { ignoreInferredTypes, enforcement, fixerConfigs, suggestionsConfigs } =
780+
optionsToUse;
781+
782+
if (ignoreInferredTypes) {
783+
return [];
784+
}
785+
717786
const immutability = getTypeImmutabilityOfType(
718-
returnTypes[0]!,
787+
returnType,
719788
context,
720789
enforcement,
721790
);
@@ -744,7 +813,7 @@
744813
},
745814
fix,
746815
suggest:
747816
suggestionFixers?.map(({ fix, message }) => ({
748817
messageId: "userDefined",
749818
data: {
750819
message,
@@ -760,9 +829,11 @@
760829
*/
761830
function checkFunction(
762831
node: ESFunctionType,
763-
context: Readonly<RuleContext<keyof typeof errorMessages, Options>>,
764-
options: Readonly<Options>,
765-
): RuleResult<keyof typeof errorMessages, Options> {
832+
context: Readonly<RuleContext<keyof typeof errorMessages, RawOptions>>,
833+
rawOptions: Readonly<RawOptions>,
834+
): RuleResult<keyof typeof errorMessages, RawOptions> {
835+
const options = upgradeRawOverridableOptions(rawOptions[0]);
836+
766837
const descriptors = [
767838
...getParameterTypeViolations(node, context, options),
768839
...getReturnTypeViolations(node, context, options),
@@ -779,16 +850,28 @@
779850
*/
780851
function checkVariable(
781852
node: TSESTree.VariableDeclarator | TSESTree.PropertyDefinition,
782-
context: Readonly<RuleContext<keyof typeof errorMessages, Options>>,
783-
options: Readonly<Options>,
784-
): RuleResult<keyof typeof errorMessages, Options> {
785-
const [optionsObject] = options;
853+
context: Readonly<RuleContext<keyof typeof errorMessages, RawOptions>>,
854+
rawOptions: Readonly<RawOptions>,
855+
): RuleResult<keyof typeof errorMessages, RawOptions> {
856+
const options = upgradeRawOverridableOptions(rawOptions[0]);
857+
const optionsToUse = getCoreOptions<CoreOptions, Options>(
858+
node,
859+
context,
860+
options,
861+
);
862+
863+
if (optionsToUse === null) {
864+
return {
865+
context,
866+
descriptors: [],
867+
};
868+
}
786869

787870
const {
788871
variables: rawOption,
789872
fixer: rawFixerConfig,
790873
suggestions: rawSuggestionsConfigs,
791-
} = optionsObject;
874+
} = optionsToUse;
792875
const {
793876
enforcement: rawEnforcement,
794877
ignoreInferredTypes,
@@ -797,16 +880,16 @@
797880
ignoreTypePattern,
798881
ignoreInFunctions,
799882
} = {
800-
ignoreInferredTypes: optionsObject.ignoreInferredTypes,
801-
ignoreClasses: optionsObject.ignoreClasses,
802-
ignoreNamePattern: optionsObject.ignoreNamePattern,
803-
ignoreTypePattern: optionsObject.ignoreTypePattern,
883+
ignoreInferredTypes: optionsToUse.ignoreInferredTypes,
884+
ignoreClasses: optionsToUse.ignoreClasses,
885+
ignoreNamePattern: optionsToUse.ignoreNamePattern,
886+
ignoreTypePattern: optionsToUse.ignoreTypePattern,
804887
ignoreInFunctions: false,
805888
...(typeof rawOption === "object" ? rawOption : { enforcement: rawOption }),
806889
};
807890

808891
const enforcement = parseEnforcement(
809-
rawEnforcement ?? optionsObject.enforcement,
892+
rawEnforcement ?? optionsToUse.enforcement,
810893
);
811894

812895
if (
@@ -931,7 +1014,7 @@
9311014
data,
9321015
fix,
9331016
suggest:
9341017
suggestionFixers?.map(({ fix, message }) => ({
9351018
messageId: "userDefined",
9361019
data: {
9371020
message,
@@ -944,9 +1027,9 @@
9441027
}
9451028

9461029
// Create the rule.
947-
export const rule: Rule<keyof typeof errorMessages, Options> = createRule<
1030+
export const rule: Rule<keyof typeof errorMessages, RawOptions> = createRule<
9481031
keyof typeof errorMessages,
949-
Options
1032+
RawOptions
9501033
>(name, meta, defaultOptions, {
9511034
ArrowFunctionExpression: checkFunction,
9521035
FunctionDeclaration: checkFunction,

0 commit comments

Comments
 (0)
Please sign in to comment.