eslint-plugin-ts-data-forge 0.10.3 → 0.10.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 (63) hide show
  1. package/dist/rules/mutable-result.mjs.map +1 -1
  2. package/dist/rules/no-unnecessary-type-guard.mjs +1 -1
  3. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  4. package/dist/rules/prefer-arr-generate.mjs +1 -1
  5. package/dist/rules/prefer-arr-generate.mjs.map +1 -1
  6. package/dist/rules/prefer-arr-is-bounded-length-array.mjs +1 -1
  7. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  8. package/dist/rules/prefer-arr-is-fixed-length-array.mjs +1 -1
  9. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  10. package/dist/rules/prefer-arr-is-max-length-array.mjs +1 -1
  11. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  12. package/dist/rules/prefer-arr-is-min-length-array.mjs +1 -1
  13. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  14. package/dist/rules/prefer-arr-is-non-empty.mjs +1 -1
  15. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  16. package/dist/rules/prefer-arr-scan.d.mts.map +1 -1
  17. package/dist/rules/prefer-arr-scan.mjs +5 -2
  18. package/dist/rules/prefer-arr-scan.mjs.map +1 -1
  19. package/dist/rules/prefer-arr-sum.mjs +1 -1
  20. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  21. package/dist/rules/prefer-arr-uniq.mjs +1 -1
  22. package/dist/rules/prefer-arr-uniq.mjs.map +1 -1
  23. package/dist/rules/prefer-as-int.mjs +1 -1
  24. package/dist/rules/prefer-as-int.mjs.map +1 -1
  25. package/dist/rules/prefer-canonical-array-slicing.mjs +1 -1
  26. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  27. package/dist/rules/prefer-canonical-length-cast.mjs +1 -1
  28. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  29. package/dist/rules/prefer-canonical-length-guard.mjs +1 -1
  30. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  31. package/dist/rules/prefer-comparison-over-nullish-guard.mjs +1 -1
  32. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  33. package/dist/rules/prefer-obj-over-entries-round-trip.mjs +1 -1
  34. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  35. package/dist/rules/prefer-pipe-map-nullable.mjs +1 -1
  36. package/dist/rules/prefer-pipe-map-nullable.mjs.map +1 -1
  37. package/dist/rules/prefer-range-for-loop.mjs +1 -1
  38. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  39. package/package.json +9 -9
  40. package/src/rules/mutable-result.mts +1 -1
  41. package/src/rules/no-unnecessary-type-guard.mts +1 -1
  42. package/src/rules/prefer-arr-generate.mts +1 -1
  43. package/src/rules/prefer-arr-is-array.test.mts +87 -5
  44. package/src/rules/prefer-arr-is-bounded-length-array.mts +1 -1
  45. package/src/rules/prefer-arr-is-fixed-length-array.mts +1 -1
  46. package/src/rules/prefer-arr-is-max-length-array.mts +1 -1
  47. package/src/rules/prefer-arr-is-min-length-array.mts +1 -1
  48. package/src/rules/prefer-arr-is-non-empty.mts +1 -1
  49. package/src/rules/prefer-arr-scan.mts +5 -2
  50. package/src/rules/prefer-arr-sum.mts +1 -1
  51. package/src/rules/prefer-arr-uniq.mts +1 -1
  52. package/src/rules/prefer-as-int.mts +1 -1
  53. package/src/rules/prefer-canonical-array-slicing.mts +2 -2
  54. package/src/rules/prefer-canonical-length-cast.mts +1 -1
  55. package/src/rules/prefer-canonical-length-guard.mts +1 -1
  56. package/src/rules/prefer-comparison-over-nullish-guard.mts +3 -3
  57. package/src/rules/prefer-is-non-null-object.test.mts +62 -37
  58. package/src/rules/prefer-is-record-and-has-key.test.mts +32 -17
  59. package/src/rules/prefer-num-safe-parse-float.test.mts +45 -21
  60. package/src/rules/prefer-num-safe-parse-int.test.mts +29 -14
  61. package/src/rules/prefer-obj-over-entries-round-trip.mts +1 -1
  62. package/src/rules/prefer-pipe-map-nullable.mts +2 -2
  63. package/src/rules/prefer-range-for-loop.mts +1 -1
@@ -32,6 +32,7 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
32
32
  useIsBoundedLengthArray:
33
33
  'Replace `{{original}}` with `Arr.isBoundedLengthArray({{arrayName}}, {{min}}, {{max}})` from ts-data-forge.',
34
34
  },
35
+ defaultOptions: [],
35
36
  },
36
37
 
37
38
  create: (context) => {
@@ -141,5 +142,4 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
141
142
  },
142
143
  };
143
144
  },
144
- defaultOptions: [],
145
145
  } as const;
@@ -33,6 +33,7 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
33
33
  useIsFixedLengthArray:
34
34
  'Replace `{{original}}` with `Arr.isFixedLengthArray({{arrayName}}, {{length}})` from ts-data-forge.',
35
35
  },
36
+ defaultOptions: [],
36
37
  },
37
38
 
38
39
  create: (context) => {
@@ -139,5 +140,4 @@ export const preferArrIsFixedLengthArray: TSESLint.RuleModule<
139
140
  },
140
141
  };
141
142
  },
142
- defaultOptions: [],
143
143
  } as const;
@@ -34,6 +34,7 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
34
34
  useIsMaxLengthArray:
35
35
  'Replace `{{original}}` with `Arr.isMaxLengthArray({{arrayName}}, {{length}})` from ts-data-forge.',
36
36
  },
37
+ defaultOptions: [],
37
38
  },
38
39
 
39
40
  create: (context) => {
@@ -142,5 +143,4 @@ export const preferArrIsMaxLengthArray: TSESLint.RuleModule<
142
143
  },
143
144
  };
144
145
  },
145
- defaultOptions: [],
146
146
  } as const;
@@ -34,6 +34,7 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
34
34
  useIsMinLengthArray:
35
35
  'Replace `{{original}}` with `Arr.isMinLengthArray({{arrayName}}, {{length}})` from ts-data-forge.',
36
36
  },
37
+ defaultOptions: [],
37
38
  },
38
39
 
39
40
  create: (context) => {
@@ -142,5 +143,4 @@ export const preferArrIsMinLengthArray: TSESLint.RuleModule<
142
143
  },
143
144
  };
144
145
  },
145
- defaultOptions: [],
146
146
  } as const;
@@ -30,6 +30,7 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
30
30
  useIsNonEmpty:
31
31
  'Replace `{{original}}` with `Arr.isNonEmpty({{arrayName}})` from ts-data-forge.',
32
32
  },
33
+ defaultOptions: [],
33
34
  },
34
35
 
35
36
  create: (context) => {
@@ -125,5 +126,4 @@ export const preferArrIsNonEmpty: TSESLint.RuleModule<MessageIds, Options> = {
125
126
  },
126
127
  };
127
128
  },
128
- defaultOptions: [],
129
129
  } as const;
@@ -21,7 +21,10 @@ type Options = readonly [];
21
21
  type MessageIds = 'preferArrScanPrefix' | 'preferArrScanAccumulate';
22
22
 
23
23
  /** Array methods that cut a prefix or a suffix out of the array they are called on. */
24
- const SLICING_METHODS: ReadonlySet<string> = new Set(['slice', 'subarray']);
24
+ const SLICING_METHODS: ReadonlySet<string> = new Set<string>([
25
+ 'slice',
26
+ 'subarray',
27
+ ]);
25
28
 
26
29
  /** A `map` call whose callback ignores the element it is handed. */
27
30
  type PrefixCandidate = Readonly<{
@@ -171,6 +174,7 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
171
174
  preferArrScanAccumulate:
172
175
  'Rebuilding the accumulator array on every step copies it each time. `Arr.scan` from ts-data-forge accumulates in one pass and returns the initial value followed by every intermediate one.',
173
176
  },
177
+ defaultOptions: [],
174
178
  },
175
179
 
176
180
  create: (context) => {
@@ -553,7 +557,6 @@ export const preferArrScan: TSESLint.RuleModule<MessageIds, Options> = {
553
557
  },
554
558
  };
555
559
  },
556
- defaultOptions: [],
557
560
  } as const;
558
561
 
559
562
  /**
@@ -33,6 +33,7 @@ export const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {
33
33
  useArrSumBy:
34
34
  'Replace with `Arr.sumBy({{arrayName}}, {{mapper}})` from ts-data-forge.',
35
35
  },
36
+ defaultOptions: [],
36
37
  },
37
38
 
38
39
  create: (context) => {
@@ -306,5 +307,4 @@ export const preferArrSum: TSESLint.RuleModule<MessageIds, Options> = {
306
307
  },
307
308
  };
308
309
  },
309
- defaultOptions: [],
310
310
  } as const;
@@ -45,6 +45,7 @@ export const preferArrUniq: TSESLint.RuleModule<MessageIds, Options> = {
45
45
  suggestArrUniq:
46
46
  'Replace with `Arr.uniq({{arrayName}})` from ts-data-forge (the result becomes a readonly array).',
47
47
  },
48
+ defaultOptions: [],
48
49
  },
49
50
 
50
51
  create: (context) => {
@@ -213,7 +214,6 @@ export const preferArrUniq: TSESLint.RuleModule<MessageIds, Options> = {
213
214
  },
214
215
  };
215
216
  },
216
- defaultOptions: [],
217
217
  } as const;
218
218
 
219
219
  /**
@@ -30,6 +30,7 @@ export const preferAsInt: TSESLint.RuleModule<MessageIds, Options> = {
30
30
  useBrandedNumberCastFunction:
31
31
  'Replace `as {{typeName}}` with `{{functionName}}()` from ts-data-forge.',
32
32
  },
33
+ defaultOptions: [],
33
34
  },
34
35
 
35
36
  create: (context) => {
@@ -112,7 +113,6 @@ export const preferAsInt: TSESLint.RuleModule<MessageIds, Options> = {
112
113
  },
113
114
  };
114
115
  },
115
- defaultOptions: [],
116
116
  } as const;
117
117
 
118
118
  const getBrandedNumberTypeInfo = (
@@ -113,7 +113,7 @@ const rootIdentifierName = (wrapped: TSESTree.Node): string | undefined => {
113
113
 
114
114
  type ComparisonOperator = '!==' | '<' | '<=' | '>' | '>=';
115
115
 
116
- const COMPARISON_OPERATORS: ReadonlySet<string> = new Set([
116
+ const COMPARISON_OPERATORS: ReadonlySet<string> = new Set<string>([
117
117
  '!==',
118
118
  '<',
119
119
  '<=',
@@ -192,6 +192,7 @@ export const preferCanonicalArraySlicing: TSESLint.RuleModule<
192
192
  preferCanonicalArraySlicing:
193
193
  'Replace with `{{replacement}}` from ts-data-forge.',
194
194
  },
195
+ defaultOptions: [],
195
196
  },
196
197
 
197
198
  create: (context) => {
@@ -877,5 +878,4 @@ export const preferCanonicalArraySlicing: TSESLint.RuleModule<
877
878
  },
878
879
  };
879
880
  },
880
- defaultOptions: [],
881
881
  } as const;
@@ -141,6 +141,7 @@ export const preferCanonicalLengthCast: TSESLint.RuleModule<
141
141
  useCanonicalCast:
142
142
  'Use `{{arrName}}.{{replacement}}(...)` instead of `{{arrName}}.{{cast}}({{boundsText}})`: with these bounds the result type is the same (or stricter), and `{{replacement}}` names the constraint directly.',
143
143
  },
144
+ defaultOptions: [],
144
145
  },
145
146
 
146
147
  create: (context) => {
@@ -197,7 +198,6 @@ export const preferCanonicalLengthCast: TSESLint.RuleModule<
197
198
  },
198
199
  };
199
200
  },
200
- defaultOptions: [],
201
201
  } as const;
202
202
 
203
203
  /** The `Arr.<cast>` method name of `node`, or `undefined` for other calls. */
@@ -116,6 +116,7 @@ export const preferCanonicalLengthGuard: TSESLint.RuleModule<
116
116
  fixable: 'code',
117
117
  schema: [],
118
118
  messages: MESSAGES,
119
+ defaultOptions: [],
119
120
  },
120
121
 
121
122
  create: (context) => {
@@ -180,7 +181,6 @@ export const preferCanonicalLengthGuard: TSESLint.RuleModule<
180
181
  },
181
182
  ]);
182
183
  },
183
- defaultOptions: [],
184
184
  } as const;
185
185
 
186
186
  /**
@@ -36,7 +36,7 @@ const COMPARISON_GUARDS: ReadonlyRecord<string, ComparisonSpec> = {
36
36
  * intended, but are parenthesized so that the type or the grouping is not read
37
37
  * as part of the comparison.
38
38
  */
39
- const ARG_NEEDS_PARENS: ReadonlySet<string> = new Set([
39
+ const ARG_NEEDS_PARENS: ReadonlySet<string> = new Set<string>([
40
40
  AST_NODE_TYPES.LogicalExpression,
41
41
  AST_NODE_TYPES.ConditionalExpression,
42
42
  AST_NODE_TYPES.AssignmentExpression,
@@ -48,7 +48,7 @@ const ARG_NEEDS_PARENS: ReadonlySet<string> = new Set([
48
48
  ]);
49
49
 
50
50
  /** Binary operators that bind no tighter than `===` / `!==`. */
51
- const LOOSE_BINARY_OPERATORS: ReadonlySet<string> = new Set([
51
+ const LOOSE_BINARY_OPERATORS: ReadonlySet<string> = new Set<string>([
52
52
  '|',
53
53
  '^',
54
54
  '&',
@@ -116,6 +116,7 @@ export const preferComparisonOverNullishGuard: TSESLint.RuleModule<
116
116
  preferComparison:
117
117
  'Prefer `{{comparison}}` over calling `{{name}}` with an explicit argument.',
118
118
  },
119
+ defaultOptions: [],
119
120
  },
120
121
 
121
122
  create: (context) => {
@@ -171,5 +172,4 @@ export const preferComparisonOverNullishGuard: TSESLint.RuleModule<
171
172
  },
172
173
  };
173
174
  },
174
- defaultOptions: [],
175
175
  } as const;
@@ -60,24 +60,6 @@ describe('prefer-is-non-null-object', () => {
60
60
  `,
61
61
  errors: [{ messageId: 'useIsNonNullObject' }],
62
62
  },
63
- {
64
- name: 'replaces multiple typeof object checks with isNonNullObject imports',
65
- code: dedent`
66
- const u = {};
67
- const ok = typeof u === "object" && u !== null;
68
- const ok2 = typeof u === "object" && u !== null;
69
- `,
70
- output: dedent`
71
- import { isNonNullObject } from 'ts-data-forge';
72
- const u = {};
73
- const ok = isNonNullObject(u);
74
- const ok2 = isNonNullObject(u);
75
- `,
76
- errors: [
77
- { messageId: 'useIsNonNullObject' },
78
- { messageId: 'useIsNonNullObject' },
79
- ],
80
- },
81
63
  ] as const),
82
64
 
83
65
  ...([
@@ -124,8 +106,7 @@ describe('prefer-is-non-null-object', () => {
124
106
  const ok = typeof u === "object" && u !== null;
125
107
  `,
126
108
  output: dedent`
127
- import { isNonNullObject } from 'ts-data-forge';
128
- import { asInt } from 'ts-data-forge';
109
+ import { asInt, isNonNullObject } from 'ts-data-forge';
129
110
 
130
111
  const ok = isNonNullObject(u);
131
112
  `,
@@ -141,9 +122,8 @@ describe('prefer-is-non-null-object', () => {
141
122
  noop(typeof u === "object" && u !== null);
142
123
  `,
143
124
  output: dedent`
144
- import { isNonNullObject } from 'ts-data-forge';
145
125
  import { noop } from './noop.mjs';
146
- import { asInt } from 'ts-data-forge';
126
+ import { asInt, isNonNullObject } from 'ts-data-forge';
147
127
 
148
128
  const u = {};
149
129
  noop(isNonNullObject(u));
@@ -151,6 +131,32 @@ describe('prefer-is-non-null-object', () => {
151
131
  errors: [{ messageId: 'useIsNonNullObject' }],
152
132
  },
153
133
  ] as const),
134
+ {
135
+ name: 'replaces multiple typeof object checks with isNonNullObject imports',
136
+ code: dedent`
137
+ const u = {};
138
+ const ok = typeof u === "object" && u !== null;
139
+ const ok2 = typeof u === "object" && u !== null;
140
+ `,
141
+ output: [
142
+ dedent`
143
+ import { isNonNullObject } from 'ts-data-forge';
144
+ const u = {};
145
+ const ok = isNonNullObject(u);
146
+ const ok2 = typeof u === "object" && u !== null;
147
+ `,
148
+ dedent`
149
+ import { isNonNullObject } from 'ts-data-forge';
150
+ const u = {};
151
+ const ok = isNonNullObject(u);
152
+ const ok2 = isNonNullObject(u);
153
+ `,
154
+ ],
155
+ errors: [
156
+ { messageId: 'useIsNonNullObject' },
157
+ { messageId: 'useIsNonNullObject' },
158
+ ],
159
+ },
154
160
  ],
155
161
  });
156
162
  }, 20000);
@@ -298,15 +304,26 @@ describe('prefer-is-non-null-object in other forms', () => {
298
304
  const y = a && typeof u === 'object' && u !== null;
299
305
  const z = a && u !== null && (typeof u === 'object') && b;
300
306
  `,
301
- output: dedent`
302
- import { isNonNullObject } from 'ts-data-forge';
303
- declare const u: unknown;
304
- declare const a: boolean;
305
- declare const b: boolean;
306
- const x = isNonNullObject(u) && 'k' in u;
307
- const y = a && isNonNullObject(u);
308
- const z = a && isNonNullObject(u) && b;
309
- `,
307
+ output: [
308
+ dedent`
309
+ import { isNonNullObject } from 'ts-data-forge';
310
+ declare const u: unknown;
311
+ declare const a: boolean;
312
+ declare const b: boolean;
313
+ const x = isNonNullObject(u) && 'k' in u;
314
+ const y = a && typeof u === 'object' && u !== null;
315
+ const z = a && u !== null && (typeof u === 'object') && b;
316
+ `,
317
+ dedent`
318
+ import { isNonNullObject } from 'ts-data-forge';
319
+ declare const u: unknown;
320
+ declare const a: boolean;
321
+ declare const b: boolean;
322
+ const x = isNonNullObject(u) && 'k' in u;
323
+ const y = a && isNonNullObject(u);
324
+ const z = a && isNonNullObject(u) && b;
325
+ `,
326
+ ],
310
327
  errors: [
311
328
  { messageId: 'useIsNonNullObject' },
312
329
  { messageId: 'useIsNonNullObject' },
@@ -320,12 +337,20 @@ describe('prefer-is-non-null-object in other forms', () => {
320
337
  declare const v: unknown;
321
338
  const ok = typeof u === 'object' && u !== null && v !== null && typeof v === 'object';
322
339
  `,
323
- output: dedent`
324
- import { isNonNullObject } from 'ts-data-forge';
325
- declare const u: unknown;
326
- declare const v: unknown;
327
- const ok = isNonNullObject(u) && isNonNullObject(v);
328
- `,
340
+ output: [
341
+ dedent`
342
+ import { isNonNullObject } from 'ts-data-forge';
343
+ declare const u: unknown;
344
+ declare const v: unknown;
345
+ const ok = isNonNullObject(u) && v !== null && typeof v === 'object';
346
+ `,
347
+ dedent`
348
+ import { isNonNullObject } from 'ts-data-forge';
349
+ declare const u: unknown;
350
+ declare const v: unknown;
351
+ const ok = isNonNullObject(u) && isNonNullObject(v);
352
+ `,
353
+ ],
329
354
  errors: [
330
355
  { messageId: 'useIsNonNullObject' },
331
356
  { messageId: 'useIsNonNullObject' },
@@ -85,13 +85,22 @@ describe('prefer-is-record-and-has-key', () => {
85
85
  const a = Object.hasOwn(rec, 'a');
86
86
  const b = Object.hasOwn(unk, 'b');
87
87
  `,
88
- output: dedent`
89
- import { isRecord, hasKey } from 'ts-data-forge';
90
- declare const rec: Record<string, unknown>;
91
- declare const unk: unknown;
92
- const a = hasKey(rec, 'a');
93
- const b = (isRecord(unk) && hasKey(unk, 'b'));
94
- `,
88
+ output: [
89
+ dedent`
90
+ import { hasKey } from 'ts-data-forge';
91
+ declare const rec: Record<string, unknown>;
92
+ declare const unk: unknown;
93
+ const a = hasKey(rec, 'a');
94
+ const b = Object.hasOwn(unk, 'b');
95
+ `,
96
+ dedent`
97
+ import { hasKey, isRecord } from 'ts-data-forge';
98
+ declare const rec: Record<string, unknown>;
99
+ declare const unk: unknown;
100
+ const a = hasKey(rec, 'a');
101
+ const b = (isRecord(unk) && hasKey(unk, 'b'));
102
+ `,
103
+ ],
95
104
  errors: [
96
105
  { messageId: 'useHasKey' },
97
106
  { messageId: 'useIsRecordAndHasKey' },
@@ -162,8 +171,7 @@ describe('prefer-is-record-and-has-key', () => {
162
171
  const ok = Object.hasOwn(obj, 'a');
163
172
  `,
164
173
  output: dedent`
165
- import { hasKey } from 'ts-data-forge';
166
- import { isRecord } from 'ts-data-forge';
174
+ import { isRecord, hasKey } from 'ts-data-forge';
167
175
 
168
176
  const obj = { a: 1 };
169
177
  const ok = (isRecord(obj) && hasKey(obj, 'a'));
@@ -179,8 +187,7 @@ describe('prefer-is-record-and-has-key', () => {
179
187
  const ok = 'a' in obj;
180
188
  `,
181
189
  output: dedent`
182
- import { isRecord } from 'ts-data-forge';
183
- import { hasKey } from 'ts-data-forge';
190
+ import { hasKey, isRecord } from 'ts-data-forge';
184
191
 
185
192
  const obj = { a: 1 };
186
193
  const ok = (isRecord(obj) && hasKey(obj, 'a'));
@@ -210,12 +217,20 @@ describe('prefer-is-record-and-has-key', () => {
210
217
  const ok1 = Object.hasOwn(obj, 'a');
211
218
  const ok2 = 'b' in obj;
212
219
  `,
213
- output: dedent`
214
- import { isRecord, hasKey } from 'ts-data-forge';
215
- const obj = { a: 1 };
216
- const ok1 = (isRecord(obj) && hasKey(obj, 'a'));
217
- const ok2 = (isRecord(obj) && hasKey(obj, 'b'));
218
- `,
220
+ output: [
221
+ dedent`
222
+ import { isRecord, hasKey } from 'ts-data-forge';
223
+ const obj = { a: 1 };
224
+ const ok1 = (isRecord(obj) && hasKey(obj, 'a'));
225
+ const ok2 = 'b' in obj;
226
+ `,
227
+ dedent`
228
+ import { isRecord, hasKey } from 'ts-data-forge';
229
+ const obj = { a: 1 };
230
+ const ok1 = (isRecord(obj) && hasKey(obj, 'a'));
231
+ const ok2 = (isRecord(obj) && hasKey(obj, 'b'));
232
+ `,
233
+ ],
219
234
  errors: [
220
235
  { messageId: 'useIsRecordAndHasKey' },
221
236
  { messageId: 'useIsRecordAndHasKey' },
@@ -105,8 +105,7 @@ describe('prefer-num-safe-parse-float', () => {
105
105
  const n = parseFloat(s);
106
106
  `,
107
107
  output: dedent`
108
- import { Result } from 'ts-data-forge';
109
- import { Num } from 'ts-data-forge';
108
+ import { Num, Result } from 'ts-data-forge';
110
109
 
111
110
  const s = "3.14";
112
111
  const n = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
@@ -145,13 +144,22 @@ describe('prefer-num-safe-parse-float', () => {
145
144
  const b = Number.parseFloat(s);
146
145
  const c = Number(s);
147
146
  `,
148
- output: dedent`
149
- import { Num, Result } from 'ts-data-forge';
150
- const s = "1.5";
151
- const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
152
- const b = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
153
- const c = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
154
- `,
147
+ output: [
148
+ dedent`
149
+ import { Num, Result } from 'ts-data-forge';
150
+ const s = "1.5";
151
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
152
+ const b = Number.parseFloat(s);
153
+ const c = Number(s);
154
+ `,
155
+ dedent`
156
+ import { Num, Result } from 'ts-data-forge';
157
+ const s = "1.5";
158
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
159
+ const b = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
160
+ const c = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
161
+ `,
162
+ ],
155
163
  errors: [
156
164
  { messageId: 'useSafeParseFloat' },
157
165
  { messageId: 'useSafeParseFloat' },
@@ -203,12 +211,20 @@ describe('prefer-num-safe-parse-float through type wrappers', () => {
203
211
  const a = Number(s!);
204
212
  const b = parseFloat(s satisfies string);
205
213
  `,
206
- output: dedent`
207
- import { Num, Result } from 'ts-data-forge';
208
- declare const s: string;
209
- const a = Result.unwrapOkOr(Num.safeParseFloat(s!), Number.NaN);
210
- const b = Result.unwrapOkOr(Num.safeParseFloat(s satisfies string), Number.NaN);
211
- `,
214
+ output: [
215
+ dedent`
216
+ import { Num, Result } from 'ts-data-forge';
217
+ declare const s: string;
218
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s!), Number.NaN);
219
+ const b = parseFloat(s satisfies string);
220
+ `,
221
+ dedent`
222
+ import { Num, Result } from 'ts-data-forge';
223
+ declare const s: string;
224
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s!), Number.NaN);
225
+ const b = Result.unwrapOkOr(Num.safeParseFloat(s satisfies string), Number.NaN);
226
+ `,
227
+ ],
212
228
  errors: [
213
229
  { messageId: 'useSafeParseFloat' },
214
230
  { messageId: 'useSafeParseFloat' },
@@ -221,12 +237,20 @@ describe('prefer-num-safe-parse-float through type wrappers', () => {
221
237
  const a = (Number as NumberConstructor)(s);
222
238
  const b = Number!.parseFloat(s);
223
239
  `,
224
- output: dedent`
225
- import { Num, Result } from 'ts-data-forge';
226
- declare const s: string;
227
- const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
228
- const b = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
229
- `,
240
+ output: [
241
+ dedent`
242
+ import { Num, Result } from 'ts-data-forge';
243
+ declare const s: string;
244
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
245
+ const b = Number!.parseFloat(s);
246
+ `,
247
+ dedent`
248
+ import { Num, Result } from 'ts-data-forge';
249
+ declare const s: string;
250
+ const a = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
251
+ const b = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
252
+ `,
253
+ ],
230
254
  errors: [
231
255
  { messageId: 'useSafeParseFloat' },
232
256
  { messageId: 'useSafeParseFloat' },
@@ -98,8 +98,7 @@ describe('prefer-num-safe-parse-int', () => {
98
98
  const n = parseInt(s, 10);
99
99
  `,
100
100
  output: dedent`
101
- import { Result } from 'ts-data-forge';
102
- import { Num } from 'ts-data-forge';
101
+ import { Num, Result } from 'ts-data-forge';
103
102
 
104
103
  const s = "123";
105
104
  const n = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
@@ -162,12 +161,20 @@ describe('prefer-num-safe-parse-int through type wrappers', () => {
162
161
  const a = parseInt(s, 10 as const);
163
162
  const b = Number.parseInt(s!, 10 satisfies number);
164
163
  `,
165
- output: dedent`
166
- import { Num, Result } from 'ts-data-forge';
167
- declare const s: string;
168
- const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
169
- const b = Result.unwrapOkOr(Num.safeParseInt(s!), Number.NaN);
170
- `,
164
+ output: [
165
+ dedent`
166
+ import { Num, Result } from 'ts-data-forge';
167
+ declare const s: string;
168
+ const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
169
+ const b = Number.parseInt(s!, 10 satisfies number);
170
+ `,
171
+ dedent`
172
+ import { Num, Result } from 'ts-data-forge';
173
+ declare const s: string;
174
+ const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
175
+ const b = Result.unwrapOkOr(Num.safeParseInt(s!), Number.NaN);
176
+ `,
177
+ ],
171
178
  errors: [
172
179
  { messageId: 'useSafeParseInt' },
173
180
  { messageId: 'useSafeParseInt' },
@@ -180,12 +187,20 @@ describe('prefer-num-safe-parse-int through type wrappers', () => {
180
187
  const a = (parseInt as typeof parseInt)(s);
181
188
  const b = (Number as NumberConstructor)!.parseInt(s, 10);
182
189
  `,
183
- output: dedent`
184
- import { Num, Result } from 'ts-data-forge';
185
- declare const s: string;
186
- const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
187
- const b = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
188
- `,
190
+ output: [
191
+ dedent`
192
+ import { Num, Result } from 'ts-data-forge';
193
+ declare const s: string;
194
+ const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
195
+ const b = (Number as NumberConstructor)!.parseInt(s, 10);
196
+ `,
197
+ dedent`
198
+ import { Num, Result } from 'ts-data-forge';
199
+ declare const s: string;
200
+ const a = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
201
+ const b = Result.unwrapOkOr(Num.safeParseInt(s), Number.NaN);
202
+ `,
203
+ ],
189
204
  errors: [
190
205
  { messageId: 'useSafeParseInt' },
191
206
  { messageId: 'useSafeParseInt' },
@@ -86,6 +86,7 @@ export const preferObjOverEntriesRoundTrip: TSESLint.RuleModule<
86
86
  useObjFilterMap:
87
87
  'Replace this `Object.fromEntries(Object.entries(…).flatMap(…))` round trip with `Obj.filterMap` from ts-data-forge, which keeps the key types of the record in the result type.',
88
88
  },
89
+ defaultOptions: [],
89
90
  },
90
91
 
91
92
  create: (context) => {
@@ -218,7 +219,6 @@ export const preferObjOverEntriesRoundTrip: TSESLint.RuleModule<
218
219
  },
219
220
  };
220
221
  },
221
- defaultOptions: [],
222
222
  } as const;
223
223
 
224
224
  /**
@@ -53,6 +53,7 @@ export const preferPipeMapNullable: TSESLint.RuleModule<MessageIds, Options> = {
53
53
  suggestMapNullable:
54
54
  'Replace `.map({{mapNullableName}}(…))` with `.mapNullable(…)` (the inferred type may be widened, or a comment or type assertion dropped).',
55
55
  },
56
+ defaultOptions: [],
56
57
  },
57
58
 
58
59
  create: (context) => {
@@ -283,7 +284,6 @@ export const preferPipeMapNullable: TSESLint.RuleModule<MessageIds, Options> = {
283
284
  },
284
285
  };
285
286
  },
286
- defaultOptions: [],
287
287
  } as const;
288
288
 
289
289
  /**
@@ -294,7 +294,7 @@ export const preferPipeMapNullable: TSESLint.RuleModule<MessageIds, Options> = {
294
294
  const PIPE_MODULES = [TS_DATA_FORGE_MODULE, 'ts-std-forge'] as const;
295
295
 
296
296
  /** The methods of a `Pipe` that return another `Pipe`. */
297
- const PIPE_CHAIN_METHODS: ReadonlySet<string> = new Set([
297
+ const PIPE_CHAIN_METHODS: ReadonlySet<string> = new Set<string>([
298
298
  'map',
299
299
  'mapNullable',
300
300
  'mapOptional',