20 ESLint rules that enforce functional programming patterns, prevent mutations, and discourage imperative constructs. All rules are prefixed with "functional/" when used in ESLint configurations.
Enforces functional parameter patterns, ensuring functions follow functional programming principles.
/**
* Enforces functional parameter patterns
* Rule: "functional/functional-parameters"
*/
interface FunctionalParametersOptions {
/** Whether to enforce parameter count restrictions */
enforceParameterCount?: boolean | {
count: "atLeastOne" | "exactlyOne" | number;
ignoreLambdaExpression?: boolean;
ignoreIIFE?: boolean;
ignoreGettersAndSetters?: boolean;
};
/** Ignore functions matching these patterns */
ignorePattern?: string | string[];
/** Override options for specific contexts */
overrides?: OverrideSpecifier<FunctionalParametersOptions>[];
}Prevents data mutation by disallowing mutating methods and operations.
/**
* Prevents data mutation
* Rule: "functional/immutable-data"
*/
interface ImmutableDataOptions {
/** Pattern to ignore certain identifiers */
ignorePattern?: string | string[];
/** Pattern to ignore certain accessor patterns */
ignoreAccessorPattern?: string | string[];
/** Classes to treat as immutable (won't flag their methods) */
ignoreClasses?: string | string[];
/** Ignore mutations on Maps and Sets matching pattern */
ignoreMapsAndSets?: boolean | string | string[];
/** Ignore mutations of properties matching pattern */
ignoreImmediateMutation?: boolean;
/** Ignore mutations on non-const declarations */
ignoreNonConstDeclarations?: boolean | {
treatParametersAsConst: boolean;
};
}Disallows the use of class declarations and expressions.
/**
* Disallows class declarations and expressions
* Rule: "functional/no-classes"
*/
interface NoClassesOptions {
/** Pattern to ignore certain class names */
ignorePattern?: string | string[];
}Disallows class inheritance using extends keyword.
/**
* Disallows class inheritance
* Rule: "functional/no-class-inheritance"
*/
interface NoClassInheritanceOptions {
/** Pattern to ignore certain class names */
ignorePattern?: string | string[];
}Disallows conditional statements like if, switch, and ternary operators.
/**
* Disallows conditional statements
* Rule: "functional/no-conditional-statements"
*/
interface NoConditionalStatementsOptions {
/** Allow conditionals that return early (guard clauses) */
allowReturningBranches?: boolean | "ifElse" | "ifElseIf";
/** Pattern to ignore certain identifiers */
ignorePattern?: string | string[];
}Disallows expression statements, encouraging functional expressions instead.
/**
* Disallows expression statements
* Rule: "functional/no-expression-statements"
*/
interface NoExpressionStatementsOptions {
/** Pattern to ignore certain expressions */
ignorePattern?: string | string[];
/** Ignore void expressions (expressions used for side effects) */
ignoreVoid?: boolean;
/** Ignore self-returning methods like forEach */
ignoreSelfReturning?: boolean;
}Disallows let declarations, encouraging const instead.
/**
* Disallows let declarations
* Rule: "functional/no-let"
*/
interface NoLetOptions {
/** Allow let in for loop initializers */
allowInForLoopInit?: boolean;
/** Allow let declarations within functions */
allowInFunctions?: boolean;
/** Pattern to ignore certain variable names */
ignorePattern?: string | string[];
}Disallows loop statements like for, while, and do-while.
/**
* Disallows loop statements
* Rule: "functional/no-loop-statements"
*/
interface NoLoopStatementsOptions {
/** Pattern to ignore certain identifiers */
ignorePattern?: string | string[];
}Disallows mixing different types in type unions and intersections.
/**
* Disallows mixed types
* Rule: "functional/no-mixed-types"
*/
interface NoMixedTypesOptions {
/** Check object type members */
checkTypes?: boolean;
/** Check interface declarations */
checkInterfaces?: boolean;
/** Pattern to ignore certain type names */
ignorePattern?: string | string[];
}Disallows Promise.reject() calls, encouraging error handling through return types.
/**
* Disallows Promise.reject
* Rule: "functional/no-promise-reject"
*/
interface NoPromiseRejectOptions {
/** Pattern to ignore certain identifiers */
ignorePattern?: string | string[];
}Disallows functions that return void, encouraging pure functions.
/**
* Disallows functions returning void
* Rule: "functional/no-return-void"
*/
interface NoReturnVoidOptions {
/** Allow void returns in specific function types */
ignoreInferredTypes?: boolean;
/** Pattern to ignore certain function names */
ignorePattern?: string | string[];
}Disallows the use of this keyword, encouraging functional alternatives.
/**
* Disallows this expressions
* Rule: "functional/no-this-expressions"
*/
interface NoThisExpressionsOptions {
/** Pattern to ignore certain contexts */
ignorePattern?: string | string[];
}Disallows throw statements, encouraging error handling through return types.
/**
* Disallows throw statements
* Rule: "functional/no-throw-statements"
*/
interface NoThrowStatementsOptions {
/** Allow throw statements to reject promises */
allowToRejectPromises?: boolean;
/** Pattern to ignore certain contexts */
ignorePattern?: string | string[];
}Disallows try-catch statements, encouraging functional error handling.
/**
* Disallows try-catch statements
* Rule: "functional/no-try-statements"
*/
interface NoTryStatementsOptions {
/** Allow try-catch for specific use cases */
allowCatch?: boolean;
/** Allow finally blocks */
allowFinally?: boolean;
/** Pattern to ignore certain contexts */
ignorePattern?: string | string[];
}Prefers immutable type annotations like ReadonlyArray over mutable ones.
/**
* Prefers immutable types
* Rule: "functional/prefer-immutable-types"
*/
interface PreferImmutableTypesOptions {
/** Enforcement level for different contexts */
enforcement?: "None" | "ReadonlyShallow" | "ReadonlyDeep" | "Immutable";
/** Ignore inferred types */
ignoreInferredTypes?: boolean;
/** Specific enforcement for function parameters */
parameters?: {
enforcement?: "None" | "ReadonlyShallow" | "ReadonlyDeep" | "Immutable";
};
/** Specific enforcement for return types */
returnTypes?: {
enforcement?: "None" | "ReadonlyShallow" | "ReadonlyDeep" | "Immutable";
};
/** Override options for specific contexts */
overrides?: OverrideSpecifier<PreferImmutableTypesOptions>[];
}Prefers property signatures over method signatures in type definitions.
/**
* Prefers property signatures over method signatures
* Rule: "functional/prefer-property-signatures"
*/
interface PreferPropertySignaturesOptions {
/** Pattern to ignore certain property names */
ignorePattern?: string | string[];
}Prefers readonly type modifier in type annotations.
/**
* Prefers readonly type annotations
* Rule: "functional/prefer-readonly-type"
*/
interface PreferReadonlyTypeOptions {
/** Check object type literals */
checkImplicit?: boolean;
/** Ignore mutations within specific function types */
ignoreInFunction?: boolean | "method" | "function" | "constructor";
/** Pattern to ignore certain type names */
ignorePattern?: string | string[];
}Prefers tacit (point-free) function style when possible.
/**
* Prefers tacit (point-free) style
* Rule: "functional/prefer-tacit"
*/
interface PreferTacitOptions {
/** Assume unknown functions are single-argument and side-effect-free */
assumeTypes?: boolean;
/** Pattern to ignore certain function names */
ignorePattern?: string | string[];
}Enforces readonly type modifier usage.
/**
* Enforces readonly type modifier
* Rule: "functional/readonly-type"
*/
interface ReadonlyTypeOptions {
/** Check object type literals */
checkImplicit?: boolean;
/** Ignore mutations within specific function types */
ignoreInFunction?: boolean | "method" | "function" | "constructor";
/** Pattern to ignore certain type names */
ignorePattern?: string | string[];
}Enforces immutability in type declarations based on naming patterns.
/**
* Enforces immutability in type declarations
* Rule: "functional/type-declaration-immutability"
*/
interface TypeDeclarationImmutabilityOptions {
/** Rules for enforcing immutability based on type names */
rules: ImmutabilityRule[];
}
interface ImmutabilityRule {
/** Pattern to match type identifiers */
identifiers: string | string[];
/** Required immutability level */
immutability: "Mutable" | "ReadonlyShallow" | "ReadonlyDeep" | "Immutable";
/** How to enforce the rule */
comparator: "AtLeast" | "AtMost" | "Exactly";
/** Suggested fixes for violations */
suggestions?: SuggestionPattern[];
}
interface SuggestionPattern {
/** Pattern to match against */
pattern: string;
/** Replacement pattern */
replace: string;
}interface OverridableOptions<CoreOptions> {
/** Core rule options */
[key: string]: any;
/** Context-specific option overrides */
overrides?: Array<{
specifiers: TypeSpecifier | TypeSpecifier[];
options?: CoreOptions;
inherit?: boolean;
disable?: boolean;
}>;
}
interface TypeSpecifier {
/** Package from which types should be matched */
from?: "file" | "lib" | "package";
/** Specific type names to include */
include?: Array<string | RegExp>;
/** Type names to exclude */
exclude?: Array<string | RegExp>;
/** Specific type names to match */
name?: string | string[];
/** Type name patterns to match */
pattern?: string | string[];
/** Type name patterns to ignore */
ignoreName?: string | string[];
/** Type name patterns to ignore */
ignorePattern?: string | string[];
/** File paths to match */
path?: string | string[];
}
interface OverrideSpecifier<T> {
/** Files to apply overrides to */
specifiers?: {
from?: "file" | "lib" | "package";
name?: string | string[];
path?: string | string[];
} | Array<{
from?: "file" | "lib" | "package";
name?: string | string[];
path?: string | string[];
}>;
/** Override options */
options: T;
}
type ImmutabilityLevel = "Mutable" | "ReadonlyShallow" | "ReadonlyDeep" | "Immutable";
type RuleEnforcementComparator = "AtLeast" | "AtMost" | "Exactly";Basic Rule Usage:
import functional from "eslint-plugin-functional";
export default [
{
plugins: { functional },
rules: {
"functional/no-let": "error",
"functional/immutable-data": ["error", {
ignorePattern: "^mutable",
ignoreNonConstDeclarations: true,
}],
"functional/prefer-immutable-types": ["error", {
enforcement: "ReadonlyDeep",
parameters: { enforcement: "ReadonlyShallow" },
}],
},
},
];Advanced Configuration with Overrides:
export default [
{
plugins: { functional },
rules: {
"functional/prefer-immutable-types": ["error", {
enforcement: "None",
overrides: [
{
specifiers: { from: "file" },
options: {
parameters: { enforcement: "ReadonlyDeep" },
returnTypes: { enforcement: "ReadonlyShallow" },
},
},
],
}],
},
},
];