1 | <div align="center">
|
2 |
|
3 | ![eslint-logo](docs/assets/eslint-functional-logo.png?sanitize=true)
|
4 |
|
5 | # eslint-plugin-functional
|
6 |
|
7 | [![npm version](https://img.shields.io/npm/v/eslint-plugin-functional.svg?style=flat)](https://www.npmjs.com/package/eslint-plugin-functional)
|
8 | [![Release](https://github.com/eslint-functional/eslint-plugin-functional/actions/workflows/release.yml/badge.svg)](https://github.com/eslint-functional/eslint-plugin-functional/actions/workflows/release.yml)
|
9 | [![Coverage Status](https://codecov.io/gh/eslint-functional/eslint-plugin-functional/branch/main/graph/badge.svg)](https://codecov.io/gh/eslint-functional/eslint-plugin-functional)
|
10 | [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat)](https://github.com/semantic-release/semantic-release)
|
11 | [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat)](https://github.com/prettier/prettier)
|
12 | [![MIT license](https://img.shields.io/github/license/eslint-functional/eslint-plugin-functional.svg?style=flat)](https://opensource.org/licenses/MIT)
|
13 | [![GitHub Discussions](https://img.shields.io/github/discussions/eslint-functional/eslint-plugin-functional)](https://github.com/eslint-functional/eslint-plugin-functional/discussions)
|
14 |
|
15 | An [ESLint](http://eslint.org) plugin to disable mutation and promote functional programming in JavaScript and TypeScript.
|
16 |
|
17 | </div>
|
18 |
|
19 | ## Donate
|
20 |
|
21 | [Any donations would be much appreciated](./DONATIONS.md). π
|
22 |
|
23 | ### Enterprise Users
|
24 |
|
25 | `eslint-plugin-functional` is available as part of the Tidelift Subscription.
|
26 |
|
27 | Tidelift is working with the maintainers of `eslint-plugin-functional` and a growing network of open source maintainers to ensure your open source software supply chain meets enterprise standards now and into the future.
|
28 | [Learn more.](https://tidelift.com/subscription/pkg/npm-eslint-plugin-functional?utm_source=npm-eslint-plugin-functional&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
29 |
|
30 | ## Getting Started
|
31 |
|
32 | [See our getting started guide](./GETTING_STARTED.md).
|
33 |
|
34 | ## Rulesets
|
35 |
|
36 | The following rulesets are made available by this plugin.
|
37 |
|
38 | Presets:
|
39 |
|
40 | - **Strict** (`plugin:functional/strict`)\
|
41 | Enforce recommended rules designed to strictly enforce functional programming.
|
42 |
|
43 | - **Recommended** (`plugin:functional/recommended`)\
|
44 | 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.
|
45 |
|
46 | - **Lite** (`plugin:functional/lite`)\
|
47 | Good if you're new to functional programming or are converting a large codebase.
|
48 |
|
49 | Categorized:
|
50 |
|
51 | - **Currying** (`plugin:functional/currying`)\
|
52 | JavaScript functions support syntax that is not compatible with curried functions. To enforce currying, this syntax should be prevented.
|
53 |
|
54 | - **No Exceptions** (`plugin:functional/no-exceptions`)\
|
55 | Functional programming style does not use run-time exceptions. Instead expressions produces values to indicate errors.
|
56 |
|
57 | - **No Mutations** (`plugin:functional/no-mutations`)\
|
58 | Prevent mutating any data as that's not functional
|
59 |
|
60 | - **No Other Paradigms** (`plugin:functional/no-other-paradigms`)\
|
61 | 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.
|
62 |
|
63 | - **No Statements** (`plugin:functional/no-statements`)\
|
64 | 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.
|
65 |
|
66 | - **Stylistic** (`plugin:functional/stylistic`)\
|
67 | Enforce code styles that can be considered to be more functional.
|
68 |
|
69 | Other:
|
70 |
|
71 | - **All** (`plugin:functional/all`)\
|
72 | Enables all rules defined in this plugin.
|
73 |
|
74 | - **Off** (`plugin:functional/off`)\
|
75 | Disable all rules defined in this plugin.
|
76 |
|
77 | - **Disable Type Checked** (`plugin:functional/disable-type-checked`)\
|
78 | Disable all rules that require type information.
|
79 |
|
80 | - **External Vanilla Recommended** (`plugin:functional/external-vanilla-recommended`)\
|
81 | Configures recommended [vanilla ESLint](https://www.npmjs.com/package/eslint) rules.
|
82 |
|
83 | - **External Typescript Recommended** (`plugin:functional/external-typescript-recommended`)\
|
84 | Configures recommended [TypeScript ESLint](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin) rules.
|
85 | Enabling this ruleset will also enable the vanilla one.
|
86 |
|
87 | The [below section](#rules) gives details on which rules are enabled by each ruleset.
|
88 |
|
89 | ## Rules
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | πΌ Configurations enabled in.\
|
96 | β οΈ Configurations set to warn in.\
|
97 | π« Configurations disabled in.\
|
98 | βοΈ Set in the `lite` configuration.\
|
99 | β
Set in the `recommended` configuration.\
|
100 | π Set in the `strict` configuration.\
|
101 | π¨ Set in the `stylistic` configuration.\
|
102 | π§ Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
103 | π‘ Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
|
104 | π Requires [type information](https://typescript-eslint.io/linting/typed-linting).\
|
105 | β Deprecated.
|
106 |
|
107 | ### Currying
|
108 |
|
109 | | Name | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
110 | | :----------------------------------------------------------- | :----------------------------- | :-------------------------- | :- | :- | :- | :- | :- | :- |
|
111 | | [functional-parameters](docs/rules/functional-parameters.md) | Enforce functional parameters. | βοΈ β
π ![badge-currying][] | | | | | | |
|
112 |
|
113 | ### No Exceptions
|
114 |
|
115 | | Name | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
116 | | :------------------------------------------------------- | :----------------------------------------------------- | :------------------------------- | :- | :--- | :- | :- | :- | :- |
|
117 | | [no-promise-reject](docs/rules/no-promise-reject.md) | Disallow rejecting promises. | | | | | | | |
|
118 | | [no-throw-statements](docs/rules/no-throw-statements.md) | Disallow throwing exceptions. | βοΈ β
π ![badge-no-exceptions][] | | | | | | |
|
119 | | [no-try-statements](docs/rules/no-try-statements.md) | Disallow try-catch[-finally] and try-finally patterns. | π ![badge-no-exceptions][] | | βοΈ β
| | | | |
|
120 |
|
121 | ### No Mutations
|
122 |
|
123 | | NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
124 | | :--------------------------------------------------------------------------- | :-------------------------------------------------------------- | :------------------------------ | :- | :- | :- | :- | :- | :- |
|
125 | | [immutable-data](docs/rules/immutable-data.md) | Enforce treating data as immutable. | βοΈ β
π ![badge-no-mutations][] | | | | | π | |
|
126 | | [no-let](docs/rules/no-let.md) | Disallow mutable variables. | βοΈ β
π ![badge-no-mutations][] | | | | | | |
|
127 | | [prefer-immutable-types](docs/rules/prefer-immutable-types.md) | Require function parameters to be typed as certain immutability | βοΈ β
π ![badge-no-mutations][] | | | π§ | π‘ | π | |
|
128 | | [prefer-readonly-type](docs/rules/prefer-readonly-type.md) | Prefer readonly types over mutable types. | | | | π§ | | π | β |
|
129 | | [type-declaration-immutability](docs/rules/type-declaration-immutability.md) | Enforce the immutability of types based on patterns. | βοΈ β
π ![badge-no-mutations][] | | | π§ | π‘ | π | |
|
130 |
|
131 | ### No Other Paradigms
|
132 |
|
133 | | NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
134 | | :------------------------------------------------------- | :------------------------------------------------------------------------ | :------------------------------------ | :- | :--- | :- | :- | :- | :- |
|
135 | | [no-classes](docs/rules/no-classes.md) | Disallow classes. | βοΈ β
π ![badge-no-other-paradigms][] | | | | | | |
|
136 | | [no-mixed-types](docs/rules/no-mixed-types.md) | Restrict types so that only members of the same kind are allowed in them. | βοΈ β
π ![badge-no-other-paradigms][] | | | | | π | |
|
137 | | [no-this-expressions](docs/rules/no-this-expressions.md) | Disallow this access. | π ![badge-no-other-paradigms][] | | βοΈ β
| | | | |
|
138 |
|
139 | ### No Statements
|
140 |
|
141 | | Name | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
142 | | :------------------------------------------------------------------- | :--------------------------------------------- | :------------------------------- | :- | :- | :- | :- | :- | :- |
|
143 | | [no-conditional-statements](docs/rules/no-conditional-statements.md) | Disallow conditional statements. | β
π ![badge-no-statements][] | | βοΈ | | | π | |
|
144 | | [no-expression-statements](docs/rules/no-expression-statements.md) | Disallow expression statements. | β
π ![badge-no-statements][] | | βοΈ | | | π | |
|
145 | | [no-loop-statements](docs/rules/no-loop-statements.md) | Disallow imperative loops. | βοΈ β
π ![badge-no-statements][] | | | | | | |
|
146 | | [no-return-void](docs/rules/no-return-void.md) | Disallow functions that don't return anything. | βοΈ β
π ![badge-no-statements][] | | | | | π | |
|
147 |
|
148 | ### Stylistic
|
149 |
|
150 | | NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β | Description | πΌ | β οΈ | π« | π§ | π‘ | π | β |
|
151 | | :--------------------------------------------------------------------- | :--------------------------------------------------------------------- | :- | :- | :- | :- | :- | :- | :- |
|
152 | | [prefer-property-signatures](docs/rules/prefer-property-signatures.md) | Prefer property signatures over method signatures. | π¨ | | | | | π | |
|
153 | | [prefer-tacit](docs/rules/prefer-tacit.md) | Replaces `x => f(x)` with just `f`. | | π¨ | | | π‘ | π | |
|
154 | | [readonly-type](docs/rules/readonly-type.md) | Require consistently using either `readonly` keywords or `Readonly<T>` | π¨ | | | π§ | | π | |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 | [badge-currying]: https://img.shields.io/badge/-currying-red.svg
|
161 | [badge-no-exceptions]: https://img.shields.io/badge/-no--exceptions-blue.svg
|
162 | [badge-no-mutations]: https://img.shields.io/badge/-no--mutations-orange.svg
|
163 | [badge-no-other-paradigms]: https://img.shields.io/badge/-no--other--paradigms-yellow.svg
|
164 | [badge-no-statements]: https://img.shields.io/badge/-no--statements-purple.svg
|
165 |
|
166 | ## External Recommended Rules
|
167 |
|
168 | In addition to the above rules, there are a few other rules we recommended.
|
169 |
|
170 | These rules are what are included in the _external recommended_ rulesets.
|
171 |
|
172 | ### Vanilla Rules
|
173 |
|
174 | - [no-var](https://eslint.org/docs/rules/no-var)\
|
175 | Without this rule, it is still possible to create mutable `var` variables.
|
176 |
|
177 | - [no-param-reassign](https://eslint.org/docs/rules/no-param-reassign)\
|
178 | Don't allow function parameters to be reassigned, they should be treated as constants.
|
179 |
|
180 | - [prefer-const](https://eslint.org/docs/rules/prefer-const)\
|
181 | This rule provides a helpful fixer when converting from an imperative code style to a functional one.
|
182 |
|
183 | ### Typescript Rules
|
184 |
|
185 | - [@typescript-eslint/prefer-readonly](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-readonly.md)\
|
186 | This rule is helpful when working with classes.
|
187 |
|
188 | - [@typescript-eslint/switch-exhaustiveness-check](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md)\
|
189 | Although our [no-conditional-statements](./docs/rules/no-conditional-statements.md) rule also performs this check,
|
190 | this rule has a fixer that will implement the unimplemented cases which can be useful.
|
191 |
|
192 | ## Contributing
|
193 |
|
194 | [See our contributing guide](./CONTRIBUTING.md).
|
195 |
|
196 | ## Prior work
|
197 |
|
198 | This project started as a port of [tslint-immutable](https://github.com/jonaskello/tslint-immutable)
|
199 | which was originally inspired by [eslint-plugin-immutable](https://github.com/jhusain/eslint-plugin-immutable).
|