What is eslint-plugin-functional?
eslint-plugin-functional is an ESLint plugin that enforces functional programming best practices. It helps developers write code that is more predictable, easier to test, and less prone to bugs by discouraging side effects, mutable data, and other non-functional programming patterns.
What are eslint-plugin-functional's main functionalities?
No Mutations
This feature enforces immutability by disallowing the use of `let`, `this`, and `class`. This ensures that variables and data structures remain constant throughout the code.
module.exports = {
rules: {
'functional/no-let': 'error',
'functional/no-this-expression': 'error',
'functional/no-class': 'error'
}
};
No Expressions with Side Effects
This feature prevents the use of expressions that produce side effects, such as assignments and conditionals. This helps in maintaining pure functions that are easier to test and reason about.
module.exports = {
rules: {
'functional/no-expression-statement': 'error',
'functional/no-conditional-statement': 'error'
}
};
No Loops
This feature disallows the use of loop statements like `for`, `while`, and `do-while`. Instead, it encourages the use of higher-order functions like `map`, `filter`, and `reduce` for iteration.
module.exports = {
rules: {
'functional/no-loop-statement': 'error'
}
};
Other packages similar to eslint-plugin-functional
eslint-plugin-immutable
eslint-plugin-immutable is an ESLint plugin that enforces immutability rules in JavaScript code. It is similar to eslint-plugin-functional in that it discourages the use of mutable data structures and promotes the use of immutable patterns. However, it is more focused on immutability rather than a broader range of functional programming principles.
eslint-plugin-fp
eslint-plugin-fp is an ESLint plugin that enforces functional programming best practices. It is similar to eslint-plugin-functional but has a different set of rules and focuses more on preventing side effects and promoting pure functions. It also includes rules for avoiding certain JavaScript features that are considered non-functional.
eslint-plugin-no-loops
eslint-plugin-no-loops is an ESLint plugin that disallows the use of loop statements in JavaScript code. It is similar to the 'No Loops' feature of eslint-plugin-functional but is more specialized, focusing solely on preventing loops and encouraging the use of higher-order functions for iteration.
Rulesets
The following rulesets are made available by this plugin:
Presets:
-
Strict (plugin:functional/strict
)
Enforce recommended rules designed to strictly enforce functional programming.
-
Recommended (plugin:functional/recommended
)
Has the same goal as the strict
preset but a little more lenient, allowing for functional-like coding styles and nicer integration with non-functional 3rd-party libraries.
-
Lite (plugin:functional/lite
)
Good if you're new to functional programming or are converting a large codebase.
Categorized:
-
Currying (plugin:functional/currying
)
JavaScript functions support syntax that is not compatible with curried functions. To enforce currying, this syntax should be prevented.
-
No Exceptions (plugin:functional/no-exceptions
)
Functional programming style does not use run-time exceptions. Instead expressions produces values to indicate errors.
-
No Mutations (plugin:functional/no-mutations
)
Prevent mutating any data as that's not functional
-
No Other Paradigms (plugin:functional/no-other-paradigms
)
JavaScript is multi-paradigm, allowing not only functional, but object-oriented as well as other programming styles. To promote a functional style, prevent the use of other paradigm styles.
-
No Statements (plugin:functional/no-statements
)
In functional programming everything is an expression that produces a value. JavaScript has a lot of syntax that is just statements that does not produce a value. That syntax has to be prevented to promote a functional style.
-
Stylistic (plugin:functional/stylistic
)
Enforce code styles that can be considered to be more functional.
Other:
-
All (plugin:functional/all
)
Enables all rules defined in this plugin.
-
Off (plugin:functional/off
)
Disable all rules defined in this plugin.
-
External Vanilla Recommended (plugin:functional/external-vanilla-recommended
)
Configures recommended vanilla ESLint rules.
-
External Typescript Recommended (plugin:functional/external-typescript-recommended
)
Configures recommended TypeScript ESLint rules. Enabling this ruleset will also enable the vanilla one.
The below section gives details on which rules are enabled by each ruleset.
Rules
No Mutations Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
immutable-data | Disallow mutating objects and arrays | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | | :blue_heart: |
no-let | Disallow mutable variables | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | :green_circle: | | |
prefer-immutable-parameter-types | Require parameters to be deeply readonly | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | :green_circle: | | :thought_balloon: |
type-declaration-immutability | Enforce type immutability with patterns | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
No Other Paradigms Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
no-classes | Disallow classes | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
no-mixed-types | Disallow types that contain both callable and non-callable members | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
no-this-expressions | Disallow this access | :heavy_check_mark: | :heavy_check_mark: | | | | |
No Statements Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
no-conditional-statements | Disallow conditional statements (if and switch statements) | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | | | :thought_balloon: |
no-expression-statements | Disallow expressions to cause side-effects | :heavy_check_mark: | :heavy_check_mark: | | | | :thought_balloon: |
no-loop-statements | Disallow imperative loops | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | |
no-return-void | Disallow functions that return nothing | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :thought_balloon: |
No Exceptions Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
no-promise-reject | Disallow rejecting Promises | | | | | | |
no-throw-statements | Disallow throwing exceptions | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | :green_circle: | | |
no-try-statements | Disallow try-catch[-finally] and try-finally patterns | :heavy_check_mark: | :heavy_check_mark: | | | | |
Currying Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
functional-parameters | Functions must have functional parameters | :heavy_check_mark: | :heavy_check_mark: | :green_circle: | :green_circle: | | |
Stylistic Rules
Name | Description | :fleur_de_lis: | :speak_no_evil: | :see_no_evil: | :hear_no_evil: | :wrench: | :blue_heart: |
---|
prefer-property-signatures | Enforce property signatures over method signatures | :heavy_check_mark: | | | | | :thought_balloon: |
prefer-tacit | Tacit/Point-Free style. | :heavy_check_mark: | | | | :wrench: | :blue_heart: |
Key
Symbol | Meaning |
---|
:fleur_de_lis: | Ruleset: Current |
:speak_no_evil: | Ruleset: Strict |
:see_no_evil: | Ruleset: Recommended |
:hear_no_evil: | Ruleset: Lite |
:heavy_check_mark: | Enabled as Error |
:green_circle: | Enabled as Error with Overrides |
:wrench: | Fixable |
:thought_balloon: | Only Available for TypeScript |
:blue_heart: | Works better with TypeScript |
External Recommended Rules
In addition to the above rules, there are a few other rules we recommended.
These rules are what are included in the external recommended rulesets.
Vanilla Rules
-
no-var
Without this rule, it is still possible to create var
variables that are mutable.
-
no-param-reassign
Don't allow function parameters to be reassigned, they should be treated as constants.
-
prefer-const
This rule provides a helpful fixer when converting from an imperative code style to a functional one.
Typescript Rules
Prior work
This project started off as a port of tslint-immutable which was originally inspired by eslint-plugin-immutable.