Skip to content

Commit 0e2fcfd

Browse files
authored
Add prefer-direct-iteration rule (#3107)
1 parent c9632b9 commit 0e2fcfd

9 files changed

Lines changed: 1779 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# prefer-direct-iteration
2+
3+
📝 Prefer direct iteration over default iterator method calls.
4+
5+
💼 This rule is enabled in the following [configs](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config): ✅ `recommended`, ☑️ `unopinionated`.
6+
7+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
8+
9+
<!-- end auto-generated rule header -->
10+
<!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` -->
11+
12+
Some built-ins expose their default iterator through both `[Symbol.iterator]()` and a named method. For example, `Map#entries()` is the same iterator as `Map#[Symbol.iterator]()`, and `Array#values()` is the same iterator as `Array#[Symbol.iterator]()`.
13+
14+
When the result is immediately consumed as an iterable, the named method is redundant.
15+
16+
This rule reports:
17+
18+
- `.entries()` for `Map`, `FormData`, and `URLSearchParams`
19+
- `.values()` for `Array`, typed arrays, and `Set`
20+
- `.keys()` for `Set`
21+
22+
It intentionally does not report unknown receivers, or methods that are not equivalent to the default iterator, such as `Array#entries()`, `Map#values()`, or `Set#entries()`.
23+
24+
With [TypeScript type information](https://typescript-eslint.io/getting-started/typed-linting/), this rule can also recognize supported built-ins through type aliases and inferred references. Without type information, it only uses direct syntax and simple annotations.
25+
26+
## Examples
27+
28+
```js
29+
//
30+
const map = new Map();
31+
for (const entry of map.entries()) {}
32+
```
33+
34+
```js
35+
//
36+
const map = new Map();
37+
for (const entry of map) {}
38+
```
39+
40+
```js
41+
//
42+
const array = [1, 2, 3];
43+
const values = [...array.values()];
44+
```
45+
46+
```js
47+
//
48+
const array = [1, 2, 3];
49+
const values = [...array];
50+
```
51+
52+
```js
53+
//
54+
const map = new Map();
55+
const copy = new Map(map.entries());
56+
```
57+
58+
```js
59+
//
60+
const map = new Map();
61+
const copy = new Map(map);
62+
```
63+
64+
```js
65+
// ✅ — `Array#entries()` yields `[index, value]` pairs, while arrays iterate values by default
66+
for (const entry of array.entries()) {}
67+
```
68+
69+
```js
70+
// ✅ — unknown receiver
71+
for (const item of collection.values()) {}
72+
```

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export default [
174174
| [prefer-code-point](docs/rules/prefer-code-point.md) | Prefer `String#codePointAt(…)` over `String#charCodeAt(…)` and `String.fromCodePoint(…)` over `String.fromCharCode(…)`. | ✅ ☑️ | | 💡 |
175175
| [prefer-date-now](docs/rules/prefer-date-now.md) | Prefer `Date.now()` to get the number of milliseconds since the Unix Epoch. | ✅ ☑️ | 🔧 | |
176176
| [prefer-default-parameters](docs/rules/prefer-default-parameters.md) | Prefer default parameters over reassignment. | ✅ ☑️ | | 💡 |
177+
| [prefer-direct-iteration](docs/rules/prefer-direct-iteration.md) | Prefer direct iteration over default iterator method calls. | ✅ ☑️ | 🔧 | |
177178
| [prefer-dispose](docs/rules/prefer-dispose.md) | Prefer using `using`/`await using` over manual `try`/`finally` resource disposal. | | | 💡 |
178179
| [prefer-dom-node-append](docs/rules/prefer-dom-node-append.md) | Prefer `Element#append()` over `Node#appendChild()`. | ✅ ☑️ | 🔧 | |
179180
| [prefer-dom-node-remove](docs/rules/prefer-dom-node-remove.md) | Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`. | ✅ ☑️ | 🔧 | 💡 |

rules/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export {default as 'prefer-classlist-toggle'} from './prefer-classlist-toggle.js
113113
export {default as 'prefer-code-point'} from './prefer-code-point.js';
114114
export {default as 'prefer-date-now'} from './prefer-date-now.js';
115115
export {default as 'prefer-default-parameters'} from './prefer-default-parameters.js';
116+
export {default as 'prefer-direct-iteration'} from './prefer-direct-iteration.js';
116117
export {default as 'prefer-dispose'} from './prefer-dispose.js';
117118
export {default as 'prefer-dom-node-append'} from './prefer-dom-node-append.js';
118119
export {default as 'prefer-dom-node-remove'} from './prefer-dom-node-remove.js';

0 commit comments

Comments
 (0)