eslint-plugin-typefest 1.0.4 → 1.0.5

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.
Files changed (61) hide show
  1. package/README.md +88 -79
  2. package/dist/_internal/rule-catalog.d.ts.map +1 -1
  3. package/dist/_internal/rule-catalog.js +9 -0
  4. package/dist/_internal/rule-catalog.js.map +1 -1
  5. package/dist/_internal/rules-registry.d.ts.map +1 -1
  6. package/dist/_internal/rules-registry.js +18 -0
  7. package/dist/_internal/rules-registry.js.map +1 -1
  8. package/dist/plugin.cjs +855 -27
  9. package/dist/plugin.cjs.map +4 -4
  10. package/dist/rules/prefer-type-fest-and-all.d.ts +13 -0
  11. package/dist/rules/prefer-type-fest-and-all.d.ts.map +1 -0
  12. package/dist/rules/prefer-type-fest-and-all.js +105 -0
  13. package/dist/rules/prefer-type-fest-and-all.js.map +1 -0
  14. package/dist/rules/prefer-type-fest-array-length.d.ts +13 -0
  15. package/dist/rules/prefer-type-fest-array-length.d.ts.map +1 -0
  16. package/dist/rules/prefer-type-fest-array-length.js +77 -0
  17. package/dist/rules/prefer-type-fest-array-length.js.map +1 -0
  18. package/dist/rules/prefer-type-fest-conditional-pick-deep.d.ts +13 -0
  19. package/dist/rules/prefer-type-fest-conditional-pick-deep.d.ts.map +1 -0
  20. package/dist/rules/prefer-type-fest-conditional-pick-deep.js +75 -0
  21. package/dist/rules/prefer-type-fest-conditional-pick-deep.js.map +1 -0
  22. package/dist/rules/prefer-type-fest-less-than-or-equal.d.ts +13 -0
  23. package/dist/rules/prefer-type-fest-less-than-or-equal.d.ts.map +1 -0
  24. package/dist/rules/prefer-type-fest-less-than-or-equal.js +153 -0
  25. package/dist/rules/prefer-type-fest-less-than-or-equal.js.map +1 -0
  26. package/dist/rules/prefer-type-fest-less-than.d.ts +13 -0
  27. package/dist/rules/prefer-type-fest-less-than.d.ts.map +1 -0
  28. package/dist/rules/prefer-type-fest-less-than.js +154 -0
  29. package/dist/rules/prefer-type-fest-less-than.js.map +1 -0
  30. package/dist/rules/prefer-type-fest-optional.d.ts +13 -0
  31. package/dist/rules/prefer-type-fest-optional.d.ts.map +1 -0
  32. package/dist/rules/prefer-type-fest-optional.js +130 -0
  33. package/dist/rules/prefer-type-fest-optional.js.map +1 -0
  34. package/dist/rules/prefer-type-fest-or-all.d.ts +13 -0
  35. package/dist/rules/prefer-type-fest-or-all.d.ts.map +1 -0
  36. package/dist/rules/prefer-type-fest-or-all.js +105 -0
  37. package/dist/rules/prefer-type-fest-or-all.js.map +1 -0
  38. package/dist/rules/prefer-type-fest-union-member.d.ts +13 -0
  39. package/dist/rules/prefer-type-fest-union-member.d.ts.map +1 -0
  40. package/dist/rules/prefer-type-fest-union-member.js +159 -0
  41. package/dist/rules/prefer-type-fest-union-member.js.map +1 -0
  42. package/dist/rules/prefer-type-fest-union-to-tuple.d.ts +13 -0
  43. package/dist/rules/prefer-type-fest-union-to-tuple.d.ts.map +1 -0
  44. package/dist/rules/prefer-type-fest-union-to-tuple.js +75 -0
  45. package/dist/rules/prefer-type-fest-union-to-tuple.js.map +1 -0
  46. package/docs/rules/prefer-type-fest-and-all.md +111 -0
  47. package/docs/rules/prefer-type-fest-array-length.md +109 -0
  48. package/docs/rules/prefer-type-fest-conditional-pick-deep.md +112 -0
  49. package/docs/rules/prefer-type-fest-less-than-or-equal.md +111 -0
  50. package/docs/rules/prefer-type-fest-less-than.md +111 -0
  51. package/docs/rules/prefer-type-fest-optional.md +104 -0
  52. package/docs/rules/prefer-type-fest-or-all.md +111 -0
  53. package/docs/rules/prefer-type-fest-union-member.md +119 -0
  54. package/docs/rules/prefer-type-fest-union-to-tuple.md +108 -0
  55. package/docs/rules/presets/all.md +9 -0
  56. package/docs/rules/presets/index.md +87 -78
  57. package/docs/rules/presets/recommended-type-checked.md +74 -65
  58. package/docs/rules/presets/recommended.md +8 -0
  59. package/docs/rules/presets/strict.md +9 -0
  60. package/docs/rules/presets/type-fest-types.md +8 -0
  61. package/package.json +21 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-type-fest-union-to-tuple.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-type-fest-union-to-tuple.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAO7D;;;;;GAKG;AACH,QAAA,MAAM,8BAA8B,EAAE,UAAU,CAAC,OAAO,eAAe,CAyEjE,CAAC;AAEP;;GAEG;AACH,eAAe,8BAA8B,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * ESLint rule implementation for `prefer-type-fest-union-to-tuple`.
4
+ */
5
+ import { collectDirectNamedImportsFromSource, collectImportedTypeAliasMatches, createSafeTypeReferenceReplacementFix, } from "../_internal/imported-type-aliases.js";
6
+ import { TYPE_FEST_MODULE_SOURCE } from "../_internal/module-source.js";
7
+ import { reportWithOptionalFix } from "../_internal/rule-reporting.js";
8
+ import { createTypedRule } from "../_internal/typed-rule.js";
9
+ const unionToTupleAliasReplacements = {
10
+ TupleFromUnion: "UnionToTuple",
11
+ TuplifyUnion: "UnionToTuple",
12
+ };
13
+ /**
14
+ * ESLint rule definition for `prefer-type-fest-union-to-tuple`.
15
+ *
16
+ * @remarks
17
+ * Defines metadata, diagnostics, and suggestions/fixes for this rule.
18
+ */
19
+ const preferTypeFestUnionToTupleRule = createTypedRule({
20
+ create(context) {
21
+ const importedAliasMatches = collectImportedTypeAliasMatches(context.sourceCode, unionToTupleAliasReplacements);
22
+ const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
23
+ return {
24
+ 'TSTypeReference[typeName.type="Identifier"]'(node) {
25
+ if (node.typeName.type !== "Identifier") {
26
+ return;
27
+ }
28
+ const importedAliasMatch = importedAliasMatches.get(node.typeName.name);
29
+ if (!importedAliasMatch) {
30
+ return;
31
+ }
32
+ const aliasReplacementFix = createSafeTypeReferenceReplacementFix(node, importedAliasMatch.replacementName, typeFestDirectImports);
33
+ reportWithOptionalFix({
34
+ context,
35
+ data: {
36
+ alias: importedAliasMatch.importedName,
37
+ replacement: importedAliasMatch.replacementName,
38
+ },
39
+ fix: aliasReplacementFix,
40
+ messageId: "preferUnionToTuple",
41
+ node,
42
+ });
43
+ },
44
+ };
45
+ },
46
+ defaultOptions: [],
47
+ meta: {
48
+ deprecated: false,
49
+ docs: {
50
+ description: "require TypeFest UnionToTuple over imported aliases such as TuplifyUnion.",
51
+ frozen: false,
52
+ recommended: true,
53
+ requiresTypeChecking: false,
54
+ typefestConfigs: [
55
+ "typefest.configs.recommended",
56
+ "typefest.configs.strict",
57
+ "typefest.configs.all",
58
+ "typefest.configs.type-fest/types",
59
+ ],
60
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-union-to-tuple",
61
+ },
62
+ fixable: "code",
63
+ messages: {
64
+ preferUnionToTuple: "Prefer `{{replacement}}` from type-fest to convert unions into tuple forms instead of legacy alias `{{alias}}`.",
65
+ },
66
+ schema: [],
67
+ type: "suggestion",
68
+ },
69
+ name: "prefer-type-fest-union-to-tuple",
70
+ });
71
+ /**
72
+ * Default export for the `prefer-type-fest-union-to-tuple` rule module.
73
+ */
74
+ export default preferTypeFestUnionToTupleRule;
75
+ //# sourceMappingURL=prefer-type-fest-union-to-tuple.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-type-fest-union-to-tuple.js","sourceRoot":"","sources":["../../src/rules/prefer-type-fest-union-to-tuple.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,OAAO,EACH,mCAAmC,EACnC,+BAA+B,EAC/B,qCAAqC,GACxC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,MAAM,6BAA6B,GAAG;IAClC,cAAc,EAAE,cAAc;IAC9B,YAAY,EAAE,cAAc;CACtB,CAAC;AAEX;;;;;GAKG;AACH,MAAM,8BAA8B,GAChC,eAAe,CAAC;IACZ,MAAM,CAAC,OAAO;QACV,MAAM,oBAAoB,GAAG,+BAA+B,CACxD,OAAO,CAAC,UAAU,EAClB,6BAA6B,CAChC,CAAC;QACF,MAAM,qBAAqB,GAAG,mCAAmC,CAC7D,OAAO,CAAC,UAAU,EAClB,uBAAuB,CAC1B,CAAC;QAEF,OAAO;YACH,6CAA6C,CACzC,IAA8B;gBAE9B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBACtC,OAAO;gBACX,CAAC;gBAED,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,GAAG,CAC/C,IAAI,CAAC,QAAQ,CAAC,IAAI,CACrB,CAAC;gBACF,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACtB,OAAO;gBACX,CAAC;gBAED,MAAM,mBAAmB,GACrB,qCAAqC,CACjC,IAAI,EACJ,kBAAkB,CAAC,eAAe,EAClC,qBAAqB,CACxB,CAAC;gBAEN,qBAAqB,CAAC;oBAClB,OAAO;oBACP,IAAI,EAAE;wBACF,KAAK,EAAE,kBAAkB,CAAC,YAAY;wBACtC,WAAW,EAAE,kBAAkB,CAAC,eAAe;qBAClD;oBACD,GAAG,EAAE,mBAAmB;oBACxB,SAAS,EAAE,oBAAoB;oBAC/B,IAAI;iBACP,CAAC,CAAC;YACP,CAAC;SACJ,CAAC;IACN,CAAC;IACD,cAAc,EAAE,EAAE;IAClB,IAAI,EAAE;QACF,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE;YACF,WAAW,EACP,2EAA2E;YAC/E,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,IAAI;YACjB,oBAAoB,EAAE,KAAK;YAC3B,eAAe,EAAE;gBACb,8BAA8B;gBAC9B,yBAAyB;gBACzB,sBAAsB;gBACtB,kCAAkC;aACrC;YACD,GAAG,EAAE,gGAAgG;SACxG;QACD,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE;YACN,kBAAkB,EACd,iHAAiH;SACxH;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;KACrB;IACD,IAAI,EAAE,iCAAiC;CAC1C,CAAC,CAAC;AAEP;;GAEG;AACH,eAAe,8BAA8B,CAAC"}
@@ -0,0 +1,111 @@
1
+ # prefer-type-fest-and-all
2
+
3
+ Require TypeFest [`AndAll<TTuple>`](https://github.com/sindresorhus/type-fest/blob/main/source/and-all.d.ts) over `AllExtend<TTuple, true>` boolean-tuple checks.
4
+
5
+ ## Targeted pattern scope
6
+
7
+ This rule targets direct and namespace-qualified references to `AllExtend<TTuple, true>` imported from `type-fest`.
8
+
9
+ ## What this rule reports
10
+
11
+ - `AllExtend<TTuple, true>` when it is being used as a boolean-tuple conjunction check.
12
+
13
+ ## Why this rule exists
14
+
15
+ `AndAll` is the dedicated TypeFest helper for checking whether all boolean tuple members are `true`. It is shorter, more intention-revealing, and matches the new canonical TypeFest naming.
16
+
17
+ ## ❌ Incorrect
18
+
19
+ ```ts
20
+ import type { AllExtend } from "type-fest";
21
+
22
+ type AllFlagsTrue = AllExtend<[true, true, false], true>;
23
+ ```
24
+
25
+ ## ✅ Correct
26
+
27
+ ```ts
28
+ import type { AndAll } from "type-fest";
29
+
30
+ type AllFlagsTrue = AndAll<[true, true, false]>;
31
+ ```
32
+
33
+ ## Behavior and migration notes
34
+
35
+ - This rule only targets `AllExtend<TTuple, true>`.
36
+ - It does not report `AllExtend<TTuple, SomeOtherType>` usages.
37
+ - Namespace-qualified `type-fest` references are reported too.
38
+
39
+ ## Additional examples
40
+
41
+ ### ❌ Incorrect — Additional example
42
+
43
+ ```ts
44
+ import type * as TypeFest from "type-fest";
45
+
46
+ type Ready = TypeFest.AllExtend<[true, true, true], true>;
47
+ ```
48
+
49
+ ### ✅ Correct — Additional example
50
+
51
+ ```ts
52
+ import type { AndAll } from "type-fest";
53
+
54
+ type Ready = AndAll<[true, true, true]>;
55
+ ```
56
+
57
+ ### ✅ Correct — Non-targeted usage
58
+
59
+ ```ts
60
+ import type { AllExtend } from "type-fest";
61
+
62
+ type AllNumbers = AllExtend<[1, 2, 3], number>;
63
+ ```
64
+
65
+ ## ESLint flat config example
66
+
67
+ ```ts
68
+ import typefest from "eslint-plugin-typefest";
69
+
70
+ export default [
71
+ {
72
+ plugins: { typefest },
73
+ rules: {
74
+ "typefest/prefer-type-fest-and-all": "error",
75
+ },
76
+ },
77
+ ];
78
+ ```
79
+
80
+ ## When not to use it
81
+
82
+ Disable this rule if your codebase intentionally prefers the more general `AllExtend<TTuple, true>` spelling for boolean tuple checks.
83
+
84
+ ## Package documentation
85
+
86
+ TypeFest package documentation:
87
+
88
+ Source file: [`source/and-all.d.ts`](https://github.com/sindresorhus/type-fest/blob/main/source/and-all.d.ts)
89
+
90
+ ```ts
91
+ /**
92
+ Returns a boolean for whether all of the given elements are `true`.
93
+
94
+ Use-cases:
95
+ - Check if all conditions in a list of booleans are met.
96
+ */
97
+ export type AndAll<T extends readonly boolean[]> = AllExtend<T, true>;
98
+ ```
99
+
100
+ > **Rule catalog ID:** R077
101
+
102
+ ## Further reading
103
+
104
+ - [`type-fest` README](https://github.com/sindresorhus/type-fest)
105
+ - [`type-fest` npm documentation](https://www.npmjs.com/package/type-fest)
106
+ - [TypeScript Handbook: Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html)
107
+
108
+ ## Adoption resources
109
+
110
+ - [Rule adoption checklist](./guides/adoption-checklist.md)
111
+ - [Rollout and fix safety](./guides/rollout-and-fix-safety.md)
@@ -0,0 +1,109 @@
1
+ # prefer-type-fest-array-length
2
+
3
+ Require TypeFest [`ArrayLength<T>`](https://github.com/sindresorhus/type-fest/blob/main/source/array-length.d.ts) over array and tuple `T["length"]` type queries.
4
+
5
+ ## Targeted pattern scope
6
+
7
+ This is a type-aware rule. It targets indexed-access type queries whose object type resolves to an array or tuple.
8
+
9
+ ## What this rule reports
10
+
11
+ - `T["length"]` when `T` is an array or tuple type.
12
+
13
+ ## Why this rule exists
14
+
15
+ `ArrayLength<T>` is the dedicated TypeFest helper for array and tuple length extraction. Using it makes intent explicit and aligns with the canonical TypeFest helper name.
16
+
17
+ ## ❌ Incorrect
18
+
19
+ ```ts
20
+ type StepCount = EventSteps["length"];
21
+ ```
22
+
23
+ ## ✅ Correct
24
+
25
+ ```ts
26
+ import type { ArrayLength } from "type-fest";
27
+
28
+ type StepCount = ArrayLength<EventSteps>;
29
+ ```
30
+
31
+ ## Behavior and migration notes
32
+
33
+ - This rule requires type information.
34
+ - It only reports `T["length"]` when `T` resolves to an array-like type.
35
+ - It does not report non-array property lookups like `User["length"]`.
36
+
37
+ ## Additional examples
38
+
39
+ ### ❌ Incorrect — Additional example
40
+
41
+ ```ts
42
+ type TupleLength = readonly [1, 2, 3]["length"];
43
+ ```
44
+
45
+ ### ✅ Correct — Additional example
46
+
47
+ ```ts
48
+ import type { ArrayLength } from "type-fest";
49
+
50
+ type TupleLength = ArrayLength<readonly [1, 2, 3]>;
51
+ ```
52
+
53
+ ### ✅ Correct — Non-targeted usage
54
+
55
+ ```ts
56
+ interface User {
57
+ readonly length: number;
58
+ readonly name: string;
59
+ }
60
+
61
+ type UserLength = User["length"];
62
+ ```
63
+
64
+ ## ESLint flat config example
65
+
66
+ ```ts
67
+ import typefest from "eslint-plugin-typefest";
68
+
69
+ export default [
70
+ {
71
+ plugins: { typefest },
72
+ rules: {
73
+ "typefest/prefer-type-fest-array-length": "error",
74
+ },
75
+ },
76
+ ];
77
+ ```
78
+
79
+ ## When not to use it
80
+
81
+ Disable this rule if you prefer native indexed-access syntax for array length queries or if your project does not use type-aware linting.
82
+
83
+ ## Package documentation
84
+
85
+ TypeFest package documentation:
86
+
87
+ Source file: [`source/array-length.d.ts`](https://github.com/sindresorhus/type-fest/blob/main/source/array-length.d.ts)
88
+
89
+ ```ts
90
+ /**
91
+ Return the length of an array. Equivalent to `T['length']` where `T` extends any array.
92
+
93
+ Tuples resolve to numeric literals, while non-tuples resolve to the `number` type.
94
+ */
95
+ export type ArrayLength<T extends readonly unknown[]> = T['length'];
96
+ ```
97
+
98
+ > **Rule catalog ID:** R078
99
+
100
+ ## Further reading
101
+
102
+ - [`type-fest` README](https://github.com/sindresorhus/type-fest)
103
+ - [`type-fest` npm documentation](https://www.npmjs.com/package/type-fest)
104
+ - [TypeScript Handbook: Indexed Access Types](https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html)
105
+
106
+ ## Adoption resources
107
+
108
+ - [Rule adoption checklist](./guides/adoption-checklist.md)
109
+ - [Rollout and fix safety](./guides/rollout-and-fix-safety.md)
@@ -0,0 +1,112 @@
1
+ # prefer-type-fest-conditional-pick-deep
2
+
3
+ Require TypeFest [`ConditionalPickDeep<T, Condition, Options?>`](https://github.com/sindresorhus/type-fest/blob/main/source/conditional-pick-deep.d.ts) instead of legacy deep conditional-pick aliases.
4
+
5
+ ## Targeted pattern scope
6
+
7
+ This rule targets imported aliases that mirror deep conditional property filtering semantics (for example, `PickDeepByTypes` and `PickDeepByType`).
8
+
9
+ ## What this rule reports
10
+
11
+ - Type references that resolve to imported deep conditional-pick aliases.
12
+
13
+ ## Why this rule exists
14
+
15
+ `ConditionalPickDeep` is the canonical TypeFest helper for recursively filtering object properties by value condition. Standardizing on this utility improves consistency and readability.
16
+
17
+ ## ❌ Incorrect
18
+
19
+ ```ts
20
+ import type { PickDeepByTypes } from "type-aliases";
21
+
22
+ type StringProps = PickDeepByTypes<User, string>;
23
+ ```
24
+
25
+ ## ✅ Correct
26
+
27
+ ```ts
28
+ import type { ConditionalPickDeep } from "type-fest";
29
+
30
+ type StringProps = ConditionalPickDeep<User, string>;
31
+ ```
32
+
33
+ ## Behavior and migration notes
34
+
35
+ - `ConditionalPickDeep<T, Condition, Options?>` recursively selects keys whose values match `Condition`.
36
+ - This rule only targets known alias names that represent the same intent.
37
+ - Keep custom aliases only when they intentionally add behavior beyond deep conditional filtering.
38
+
39
+ ## Additional examples
40
+
41
+ ### ❌ Incorrect — Additional example
42
+
43
+ ```ts
44
+ import type { PickDeepByType } from "type-aliases";
45
+
46
+ type NumericProps = PickDeepByType<User, number>;
47
+ ```
48
+
49
+ ### ✅ Correct — Additional example
50
+
51
+ ```ts
52
+ import type { ConditionalPickDeep } from "type-fest";
53
+
54
+ type NumericProps = ConditionalPickDeep<User, number>;
55
+ ```
56
+
57
+ ### ✅ Correct — Repository-wide usage
58
+
59
+ ```ts
60
+ type DateProps = ConditionalPickDeep<User, Date>;
61
+ ```
62
+
63
+ ## ESLint flat config example
64
+
65
+ ```ts
66
+ import typefest from "eslint-plugin-typefest";
67
+
68
+ export default [
69
+ {
70
+ plugins: { typefest },
71
+ rules: {
72
+ "typefest/prefer-type-fest-conditional-pick-deep": "error",
73
+ },
74
+ },
75
+ ];
76
+ ```
77
+
78
+ ## When not to use it
79
+
80
+ Disable this rule if external API contracts require specific alias names.
81
+
82
+ ## Package documentation
83
+
84
+ TypeFest package documentation:
85
+
86
+ Source file: [`source/conditional-pick-deep.d.ts`](https://github.com/sindresorhus/type-fest/blob/main/source/conditional-pick-deep.d.ts)
87
+
88
+ ```ts
89
+ /**
90
+ Pick keys recursively from the shape that matches the given condition.
91
+
92
+ @category Object
93
+ */
94
+ export type ConditionalPickDeep<
95
+ Type,
96
+ Condition,
97
+ Options extends ConditionalPickDeepOptions = {},
98
+ > = ...
99
+ ```
100
+
101
+ > **Rule catalog ID:** R082
102
+
103
+ ## Further reading
104
+
105
+ - [`type-fest` README](https://github.com/sindresorhus/type-fest)
106
+ - [`type-fest` npm documentation](https://www.npmjs.com/package/type-fest)
107
+ - [TypeScript Handbook: Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html)
108
+
109
+ ## Adoption resources
110
+
111
+ - [Rule adoption checklist](./guides/adoption-checklist.md)
112
+ - [Rollout and fix safety](./guides/rollout-and-fix-safety.md)
@@ -0,0 +1,111 @@
1
+ # prefer-type-fest-less-than-or-equal
2
+
3
+ Require TypeFest [`LessThanOrEqual<A, B>`](https://github.com/sindresorhus/type-fest/blob/main/source/less-than-or-equal.d.ts) over boolean wrappers built from `GreaterThan<A, B>`.
4
+
5
+ ## Targeted pattern scope
6
+
7
+ This rule targets equivalent conditional wrappers such as `GreaterThan<A, B> extends true ? false : true` and infer-wrapped variants.
8
+
9
+ ## What this rule reports
10
+
11
+ - Conditional types equivalent to `LessThanOrEqual<A, B>` that are composed from `GreaterThan<A, B>`.
12
+
13
+ ## Why this rule exists
14
+
15
+ `LessThanOrEqual` is the canonical TypeFest numeric comparison helper for `<=` checks. Using it directly improves readability and avoids repeated wrapper patterns.
16
+
17
+ ## ❌ Incorrect
18
+
19
+ ```ts
20
+ import type { GreaterThan } from "type-fest";
21
+
22
+ type IsLessOrEqual = GreaterThan<1, 2> extends true ? false : true;
23
+ ```
24
+
25
+ ## ✅ Correct
26
+
27
+ ```ts
28
+ import type { LessThanOrEqual } from "type-fest";
29
+
30
+ type IsLessOrEqual = LessThanOrEqual<1, 2>;
31
+ ```
32
+
33
+ ## Behavior and migration notes
34
+
35
+ - This rule targets wrappers equivalent to `LessThanOrEqual<A, B>`.
36
+ - It handles direct and infer-wrapped conditional forms.
37
+ - It does not report wrappers whose boolean branches do not match `<=` semantics.
38
+
39
+ ## Additional examples
40
+
41
+ ### ❌ Incorrect — Additional example
42
+
43
+ ```ts
44
+ import type { GreaterThan } from "type-fest";
45
+
46
+ type IsLessOrEqual =
47
+ GreaterThan<4, 9> extends infer Result
48
+ ? Result extends true
49
+ ? false
50
+ : true
51
+ : never;
52
+ ```
53
+
54
+ ### ✅ Correct — Additional example
55
+
56
+ ```ts
57
+ import type { LessThanOrEqual } from "type-fest";
58
+
59
+ type IsLessOrEqual = LessThanOrEqual<4, 9>;
60
+ ```
61
+
62
+ ### ✅ Correct — Repository-wide usage
63
+
64
+ ```ts
65
+ type IsNonPositive<N extends number> = LessThanOrEqual<N, 0>;
66
+ ```
67
+
68
+ ## ESLint flat config example
69
+
70
+ ```ts
71
+ import typefest from "eslint-plugin-typefest";
72
+
73
+ export default [
74
+ {
75
+ plugins: { typefest },
76
+ rules: {
77
+ "typefest/prefer-type-fest-less-than-or-equal": "error",
78
+ },
79
+ },
80
+ ];
81
+ ```
82
+
83
+ ## When not to use it
84
+
85
+ Disable this rule if your codebase intentionally standardizes on custom numeric wrapper types.
86
+
87
+ ## Package documentation
88
+
89
+ TypeFest package documentation:
90
+
91
+ Source file: [`source/less-than-or-equal.d.ts`](https://github.com/sindresorhus/type-fest/blob/main/source/less-than-or-equal.d.ts)
92
+
93
+ ```ts
94
+ /**
95
+ Returns a boolean for whether a given number is less than or equal to another number.
96
+ */
97
+ export type LessThanOrEqual<A extends number, B extends number> = ...
98
+ ```
99
+
100
+ > **Rule catalog ID:** R085
101
+
102
+ ## Further reading
103
+
104
+ - [`type-fest` README](https://github.com/sindresorhus/type-fest)
105
+ - [`type-fest` npm documentation](https://www.npmjs.com/package/type-fest)
106
+ - [TypeScript Handbook: Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html)
107
+
108
+ ## Adoption resources
109
+
110
+ - [Rule adoption checklist](./guides/adoption-checklist.md)
111
+ - [Rollout and fix safety](./guides/rollout-and-fix-safety.md)
@@ -0,0 +1,111 @@
1
+ # prefer-type-fest-less-than
2
+
3
+ Require TypeFest [`LessThan<A, B>`](https://github.com/sindresorhus/type-fest/blob/main/source/less-than.d.ts) over boolean wrappers built from `GreaterThanOrEqual<A, B>`.
4
+
5
+ ## Targeted pattern scope
6
+
7
+ This rule targets equivalent conditional wrappers such as `GreaterThanOrEqual<A, B> extends true ? false : true` and infer-wrapped variants.
8
+
9
+ ## What this rule reports
10
+
11
+ - Conditional types equivalent to `LessThan<A, B>` that are composed from `GreaterThanOrEqual<A, B>`.
12
+
13
+ ## Why this rule exists
14
+
15
+ `LessThan` is the canonical TypeFest numeric comparison helper for strict `<` checks. Using it directly is shorter, clearer, and avoids repetitive wrapper patterns.
16
+
17
+ ## ❌ Incorrect
18
+
19
+ ```ts
20
+ import type { GreaterThanOrEqual } from "type-fest";
21
+
22
+ type IsLess = GreaterThanOrEqual<1, 2> extends true ? false : true;
23
+ ```
24
+
25
+ ## ✅ Correct
26
+
27
+ ```ts
28
+ import type { LessThan } from "type-fest";
29
+
30
+ type IsLess = LessThan<1, 2>;
31
+ ```
32
+
33
+ ## Behavior and migration notes
34
+
35
+ - This rule targets wrappers equivalent to `LessThan<A, B>`.
36
+ - It handles direct and infer-wrapped conditional forms.
37
+ - It does not report wrappers whose boolean branches do not match strict `<` semantics.
38
+
39
+ ## Additional examples
40
+
41
+ ### ❌ Incorrect — Additional example
42
+
43
+ ```ts
44
+ import type { GreaterThanOrEqual } from "type-fest";
45
+
46
+ type IsLess =
47
+ GreaterThanOrEqual<4, 9> extends infer Result
48
+ ? Result extends true
49
+ ? false
50
+ : true
51
+ : never;
52
+ ```
53
+
54
+ ### ✅ Correct — Additional example
55
+
56
+ ```ts
57
+ import type { LessThan } from "type-fest";
58
+
59
+ type IsLess = LessThan<4, 9>;
60
+ ```
61
+
62
+ ### ✅ Correct — Repository-wide usage
63
+
64
+ ```ts
65
+ type IsNegative<N extends number> = LessThan<N, 0>;
66
+ ```
67
+
68
+ ## ESLint flat config example
69
+
70
+ ```ts
71
+ import typefest from "eslint-plugin-typefest";
72
+
73
+ export default [
74
+ {
75
+ plugins: { typefest },
76
+ rules: {
77
+ "typefest/prefer-type-fest-less-than": "error",
78
+ },
79
+ },
80
+ ];
81
+ ```
82
+
83
+ ## When not to use it
84
+
85
+ Disable this rule if your codebase intentionally standardizes on custom numeric wrapper types.
86
+
87
+ ## Package documentation
88
+
89
+ TypeFest package documentation:
90
+
91
+ Source file: [`source/less-than.d.ts`](https://github.com/sindresorhus/type-fest/blob/main/source/less-than.d.ts)
92
+
93
+ ```ts
94
+ /**
95
+ Returns a boolean for whether a given number is less than another number.
96
+ */
97
+ export type LessThan<A extends number, B extends number> = ...
98
+ ```
99
+
100
+ > **Rule catalog ID:** R084
101
+
102
+ ## Further reading
103
+
104
+ - [`type-fest` README](https://github.com/sindresorhus/type-fest)
105
+ - [`type-fest` npm documentation](https://www.npmjs.com/package/type-fest)
106
+ - [TypeScript Handbook: Conditional Types](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html)
107
+
108
+ ## Adoption resources
109
+
110
+ - [Rule adoption checklist](./guides/adoption-checklist.md)
111
+ - [Rollout and fix safety](./guides/rollout-and-fix-safety.md)