or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration-presets.mdindex.mdplugin-configuration.mdrules.md
tile.json

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