eslint-plugin-remeda 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3828 -3708
- package/dist/index.d.cts +58 -186
- package/dist/index.d.ts +58 -186
- package/dist/index.js +3814 -3711
- package/docs/rules/prefer-has-atleast.md +89 -0
- package/package.json +27 -21
@@ -0,0 +1,89 @@
|
|
1
|
+
# remeda/prefer-has-atleast
|
2
|
+
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
4
|
+
|
5
|
+
<!-- end auto-generated rule header -->
|
6
|
+
|
7
|
+
When checking if an array has at least a certain number of elements, it is more expressive to use `R.hasAtLeast` instead of comparing the array's length with a number.
|
8
|
+
|
9
|
+
Additionally, when checking if an array is not empty, it's better to use `R.hasAtLeast(data, 1)` instead of negated `R.isEmpty(data)` patterns (`!R.isEmpty(data)`) because the TypeScript type narrowing works better with `hasAtLeast`.
|
10
|
+
|
11
|
+
## Rule Details
|
12
|
+
|
13
|
+
The following patterns are considered warnings:
|
14
|
+
|
15
|
+
```js
|
16
|
+
// Array length comparisons
|
17
|
+
if (array.length >= 3) {
|
18
|
+
// ...
|
19
|
+
}
|
20
|
+
|
21
|
+
if (array.length > 2) {
|
22
|
+
// ...
|
23
|
+
}
|
24
|
+
|
25
|
+
if (3 <= array.length) {
|
26
|
+
// ...
|
27
|
+
}
|
28
|
+
|
29
|
+
if (2 < array.length) {
|
30
|
+
// ...
|
31
|
+
}
|
32
|
+
|
33
|
+
// Negated isEmpty patterns (problematic for TypeScript type narrowing)
|
34
|
+
if (!R.isEmpty(array)) {
|
35
|
+
// TypeScript won't narrow the array type here
|
36
|
+
}
|
37
|
+
|
38
|
+
if (R.isEmpty(array) === false) {
|
39
|
+
// Same issue with type narrowing
|
40
|
+
}
|
41
|
+
|
42
|
+
if (R.isEmpty(array) !== true) {
|
43
|
+
// Same issue with type narrowing
|
44
|
+
}
|
45
|
+
```
|
46
|
+
|
47
|
+
The following patterns are not considered warnings:
|
48
|
+
|
49
|
+
```js
|
50
|
+
// Using hasAtLeast
|
51
|
+
if (R.hasAtLeast(array, 3)) {
|
52
|
+
// ...
|
53
|
+
}
|
54
|
+
|
55
|
+
// For non-empty checks, use hasAtLeast with 1
|
56
|
+
if (R.hasAtLeast(array, 1)) {
|
57
|
+
// TypeScript correctly narrows the type here
|
58
|
+
}
|
59
|
+
|
60
|
+
// Other length comparisons
|
61
|
+
if (array.length === 3) {
|
62
|
+
// ...
|
63
|
+
}
|
64
|
+
|
65
|
+
if (array.length < 3) {
|
66
|
+
// ...
|
67
|
+
}
|
68
|
+
|
69
|
+
if (array.length <= 3) {
|
70
|
+
// ...
|
71
|
+
}
|
72
|
+
|
73
|
+
// Regular isEmpty checks are fine
|
74
|
+
if (R.isEmpty(array)) {
|
75
|
+
// ...
|
76
|
+
}
|
77
|
+
```
|
78
|
+
|
79
|
+
## Type Safety Improvement
|
80
|
+
|
81
|
+
From Remeda documentation:
|
82
|
+
|
83
|
+
> "This guard [isEmpty] doesn't work negated because of typescript limitations! If you need to check that an array is not empty, use R.hasAtLeast(data, 1) and not !R.isEmpty(data). For strings and objects there's no way in typescript to narrow the result to a non-empty type."
|
84
|
+
|
85
|
+
Using `R.hasAtLeast(array, 1)` instead of `!R.isEmpty(array)` improves type safety because TypeScript can properly narrow the array type to a non-empty array, which helps prevent "possibly undefined" errors when accessing array elements.
|
86
|
+
|
87
|
+
## When Not To Use It
|
88
|
+
|
89
|
+
If you do not want to enforce using `R.hasAtLeast` or prefer the explicit array length comparison, you should not use this rule. However, consider enabling it at least for the negated `isEmpty` patterns to improve type safety.
|
package/package.json
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint-plugin-remeda",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.7.0",
|
4
4
|
"author": "Andrea Pontrandolfo <andrea.pontra@gmail.com>",
|
5
5
|
"description": "ESLint plugin for Remeda library.",
|
6
6
|
"type": "module",
|
7
7
|
"main": "dist/index.js",
|
8
8
|
"scripts": {
|
9
|
-
"build": "
|
9
|
+
"build": "tsdown",
|
10
10
|
"typecheck": "tsc",
|
11
11
|
"lint": "eslint",
|
12
12
|
"knip": "knip",
|
13
|
-
"publint": "publint",
|
14
13
|
"test:watch": "vitest --ui",
|
15
14
|
"test": "vitest run",
|
16
15
|
"attw": "attw --pack .",
|
17
|
-
"qa": "pnpm typecheck && pnpm test && pnpm knip &&
|
16
|
+
"qa": "pnpm typecheck && pnpm test && pnpm knip && attw",
|
18
17
|
"nuke": "rm -rf node_modules pnpm-lock.yaml",
|
19
18
|
"update:eslint-docs": "eslint-doc-generator",
|
20
19
|
"lint:eslint-docs": "pnpm update:eslint-docs -- --check",
|
@@ -22,14 +21,21 @@
|
|
22
21
|
},
|
23
22
|
"files": [
|
24
23
|
"README.md",
|
24
|
+
"LICENSE",
|
25
25
|
"dist",
|
26
26
|
"docs"
|
27
27
|
],
|
28
28
|
"exports": {
|
29
29
|
"./package.json": "./package.json",
|
30
30
|
".": {
|
31
|
-
"import":
|
32
|
-
|
31
|
+
"import": {
|
32
|
+
"types": "./dist/index.d.ts",
|
33
|
+
"import": "./dist/index.js"
|
34
|
+
},
|
35
|
+
"require": {
|
36
|
+
"types": "./dist/index.d.cts",
|
37
|
+
"require": "./dist/index.cjs"
|
38
|
+
}
|
33
39
|
}
|
34
40
|
},
|
35
41
|
"repository": {
|
@@ -42,24 +48,26 @@
|
|
42
48
|
"eslint": ">=9.0.0"
|
43
49
|
},
|
44
50
|
"devDependencies": {
|
45
|
-
"@arethetypeswrong/cli": "^0.
|
51
|
+
"@arethetypeswrong/cli": "^0.17.4",
|
52
|
+
"@sherifforg/cli": "^8.2.0",
|
46
53
|
"@types/lodash-es": "^4.17.12",
|
47
|
-
"@types/node": "^
|
48
|
-
"@
|
49
|
-
"@vitest/
|
50
|
-
"
|
51
|
-
"eslint
|
52
|
-
"eslint-
|
54
|
+
"@types/node": "^22.14.0",
|
55
|
+
"@typescript-eslint/utils": "^8.29.0",
|
56
|
+
"@vitest/coverage-v8": "^3.1.1",
|
57
|
+
"@vitest/ui": "^3.1.1",
|
58
|
+
"eslint": "9.24.0",
|
59
|
+
"eslint-config-sheriff": "^27.0.0",
|
53
60
|
"eslint-doc-generator": "^2.1.2",
|
54
61
|
"eslint-plugin-eslint-plugin": "^6.4.0",
|
55
|
-
"eslint-vitest-rule-tester": "^
|
56
|
-
"knip": "^5.
|
62
|
+
"eslint-vitest-rule-tester": "^2.2.0",
|
63
|
+
"knip": "^5.49.0",
|
64
|
+
"lodash-es": "^4.17.21",
|
57
65
|
"prettier": "^3.3.2",
|
58
|
-
"publint": "^0.
|
66
|
+
"publint": "^0.3.10",
|
59
67
|
"semantic-release": "^24.0.0",
|
60
|
-
"
|
68
|
+
"tsdown": "^0.9.1",
|
61
69
|
"typescript": "^5.5.2",
|
62
|
-
"vitest": "^
|
70
|
+
"vitest": "^3.1.1"
|
63
71
|
},
|
64
72
|
"engines": {
|
65
73
|
"node": ">=20"
|
@@ -78,7 +86,5 @@
|
|
78
86
|
"fp"
|
79
87
|
],
|
80
88
|
"license": "MIT",
|
81
|
-
"
|
82
|
-
"lodash-es": "^4.17.21"
|
83
|
-
}
|
89
|
+
"sideEffects": false
|
84
90
|
}
|