CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eslint-plugin-functional

ESLint rules to promote functional programming in TypeScript.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

rules.mddocs/

Functional Programming Rules

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.

Capabilities

Functional Parameters

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>[];
}

Immutable Data

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;
  };
}

No Classes

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[];
}

No Class Inheritance

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[];
}

No Conditional Statements

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[];
}

No Expression Statements

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;
}

No Let

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[];
}

No Loop Statements

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[];
}

No Mixed Types

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[];
}

No Promise Reject

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[];
}

No Return Void

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[];
}

No This Expressions

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[];
}

No Throw Statements

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[];
}

No Try Statements

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[];
}

Prefer Immutable Types

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>[];
}

Prefer Property Signatures

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[];
}

Prefer Readonly Type

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[];
}

Prefer Tacit

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[];
}

Readonly Type

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[];
}

Type Declaration Immutability

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;
}

Types

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";

Usage Examples

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" },
            },
          },
        ],
      }],
    },
  },
];

docs

configuration-presets.md

index.md

plugin-configuration.md

rules.md

tile.json