ESLint rules to promote functional programming in TypeScript.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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" },
},
},
],
}],
},
},
];