eslint-plugin-ts-data-forge 0.7.3 → 0.8.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/README.md +1 -0
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +1 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +15 -0
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rule-types.mjs.map +1 -1
- package/dist/rules/prefer-arr-uniq.d.mts +15 -0
- package/dist/rules/prefer-arr-uniq.d.mts.map +1 -0
- package/dist/rules/prefer-arr-uniq.mjs +350 -0
- package/dist/rules/prefer-arr-uniq.mjs.map +1 -0
- package/dist/rules/rules.d.mts +1 -0
- package/dist/rules/rules.d.mts.map +1 -1
- package/dist/rules/rules.mjs +2 -0
- package/dist/rules/rules.mjs.map +1 -1
- package/package.json +6 -4
- package/src/plugin.mts +1 -0
- package/src/rule-types.mts +16 -0
- package/src/rules/prefer-arr-uniq.mts +475 -0
- package/src/rules/prefer-arr-uniq.test.mts +455 -0
- package/src/rules/rules.mts +2 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import parser from '@typescript-eslint/parser';
|
|
2
|
+
import { RuleTester } from '@typescript-eslint/rule-tester';
|
|
3
|
+
import dedent from 'dedent';
|
|
4
|
+
import { preferArrUniq } from './prefer-arr-uniq.mjs';
|
|
5
|
+
|
|
6
|
+
const tester = new RuleTester({
|
|
7
|
+
languageOptions: {
|
|
8
|
+
parser,
|
|
9
|
+
parserOptions: {
|
|
10
|
+
ecmaVersion: 2020,
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
projectService: {
|
|
13
|
+
allowDefaultProject: ['*.ts*'],
|
|
14
|
+
},
|
|
15
|
+
tsconfigRootDir: `${import.meta.dirname}/../..`,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('prefer-arr-uniq', () => {
|
|
21
|
+
tester.run('prefer-arr-uniq', preferArrUniq, {
|
|
22
|
+
valid: [
|
|
23
|
+
{
|
|
24
|
+
name: 'ignores Arr.uniq',
|
|
25
|
+
code: dedent`
|
|
26
|
+
import { Arr } from 'ts-data-forge';
|
|
27
|
+
const xs: readonly number[] = [1, 2, 2];
|
|
28
|
+
const ys = Arr.uniq(xs);
|
|
29
|
+
`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'ignores an array of objects (Arr.uniq does not accept it)',
|
|
33
|
+
code: dedent`
|
|
34
|
+
const xs: readonly { v: number }[] = [{ v: 1 }];
|
|
35
|
+
const ys = Array.from(new Set(xs));
|
|
36
|
+
const zs = [...new Set(xs)];
|
|
37
|
+
`,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'ignores an array of unions including objects',
|
|
41
|
+
code: dedent`
|
|
42
|
+
const xs: readonly (number | { v: number })[] = [1];
|
|
43
|
+
const ys = [...new Set(xs)];
|
|
44
|
+
`,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'ignores an intersection of object arrays',
|
|
48
|
+
code: dedent`
|
|
49
|
+
declare const xs: readonly { v: number }[] & Readonly<{ brand: 'b' }>;
|
|
50
|
+
const ys = [...new Set(xs)];
|
|
51
|
+
`,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'ignores an array of unknown',
|
|
55
|
+
code: dedent`
|
|
56
|
+
const xs: readonly unknown[] = [1];
|
|
57
|
+
const ys = [...new Set(xs)];
|
|
58
|
+
`,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'ignores a string argument (not an array)',
|
|
62
|
+
code: dedent`
|
|
63
|
+
const s = 'abc';
|
|
64
|
+
const ys = Array.from(new Set(s));
|
|
65
|
+
`,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'ignores an iterable that is not an array',
|
|
69
|
+
code: dedent`
|
|
70
|
+
const m = new Map<string, number>();
|
|
71
|
+
const ys = [...new Set(m.keys())];
|
|
72
|
+
`,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'ignores a Set bound to a variable',
|
|
76
|
+
code: dedent`
|
|
77
|
+
const xs: readonly number[] = [1, 2];
|
|
78
|
+
const set = new Set(xs);
|
|
79
|
+
const has = set.has(1);
|
|
80
|
+
const ys = Array.from(set);
|
|
81
|
+
`,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'ignores Array.from with a mapping function',
|
|
85
|
+
code: dedent`
|
|
86
|
+
const xs: readonly number[] = [1, 2];
|
|
87
|
+
const ys = Array.from(new Set(xs), (x) => x * 2);
|
|
88
|
+
`,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'ignores new Set with explicit type arguments',
|
|
92
|
+
code: dedent`
|
|
93
|
+
const xs: readonly number[] = [1, 2];
|
|
94
|
+
const ys = [...new Set<number | string>(xs)];
|
|
95
|
+
`,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'ignores an empty Set and a spread argument',
|
|
99
|
+
code: dedent`
|
|
100
|
+
const xs: readonly (readonly number[])[] = [[1]];
|
|
101
|
+
const a = [...new Set()];
|
|
102
|
+
const b = Array.from(new Set(...xs));
|
|
103
|
+
`,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'ignores a spread with other elements',
|
|
107
|
+
code: dedent`
|
|
108
|
+
const xs: readonly number[] = [1, 2];
|
|
109
|
+
const ys = [0, ...new Set(xs)];
|
|
110
|
+
`,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'ignores a shadowed Set',
|
|
114
|
+
code: dedent`
|
|
115
|
+
class Set<T> { constructor(_: readonly T[]) {} *[Symbol.iterator]() {} }
|
|
116
|
+
const xs: readonly number[] = [1, 2];
|
|
117
|
+
const ys = [...new Set(xs)];
|
|
118
|
+
`,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'ignores a shadowed Array',
|
|
122
|
+
code: dedent`
|
|
123
|
+
const Array = { from: <T,>(x: Iterable<T>): T[] => [...x] };
|
|
124
|
+
const xs: readonly number[] = [1, 2];
|
|
125
|
+
const ys = Array.from(new Set(xs));
|
|
126
|
+
`,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
invalid: [
|
|
130
|
+
{
|
|
131
|
+
name: 'replaces Array.from(new Set(xs))',
|
|
132
|
+
code: dedent`
|
|
133
|
+
const xs: readonly number[] = [1, 2, 2];
|
|
134
|
+
const ys = Array.from(new Set(xs));
|
|
135
|
+
`,
|
|
136
|
+
output: dedent`
|
|
137
|
+
import { Arr } from 'ts-data-forge';
|
|
138
|
+
const xs: readonly number[] = [1, 2, 2];
|
|
139
|
+
const ys = Arr.uniq(xs);
|
|
140
|
+
`,
|
|
141
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'replaces [...new Set(xs)]',
|
|
145
|
+
code: dedent`
|
|
146
|
+
const xs: readonly string[] = ['a', 'b', 'a'];
|
|
147
|
+
const ys = [...new Set(xs)];
|
|
148
|
+
`,
|
|
149
|
+
output: dedent`
|
|
150
|
+
import { Arr } from 'ts-data-forge';
|
|
151
|
+
const xs: readonly string[] = ['a', 'b', 'a'];
|
|
152
|
+
const ys = Arr.uniq(xs);
|
|
153
|
+
`,
|
|
154
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'does not add an import when Arr is already imported',
|
|
158
|
+
code: dedent`
|
|
159
|
+
import { Arr } from 'ts-data-forge';
|
|
160
|
+
const xs = [1, 2, 2];
|
|
161
|
+
const ys = [...new Set(xs)];
|
|
162
|
+
`,
|
|
163
|
+
output: dedent`
|
|
164
|
+
import { Arr } from 'ts-data-forge';
|
|
165
|
+
const xs = [1, 2, 2];
|
|
166
|
+
const ys = Arr.uniq(xs);
|
|
167
|
+
`,
|
|
168
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'uses the local name of an aliased Arr import',
|
|
172
|
+
code: dedent`
|
|
173
|
+
import { Arr as A } from 'ts-data-forge';
|
|
174
|
+
const xs = [1, 2, 2];
|
|
175
|
+
const ys = [...new Set(xs)];
|
|
176
|
+
`,
|
|
177
|
+
output: dedent`
|
|
178
|
+
import { Arr as A } from 'ts-data-forge';
|
|
179
|
+
const xs = [1, 2, 2];
|
|
180
|
+
const ys = A.uniq(xs);
|
|
181
|
+
`,
|
|
182
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'adds the import once for several matches',
|
|
186
|
+
code: dedent`
|
|
187
|
+
const xs = ['a', 'b'];
|
|
188
|
+
const ys = [...new Set(xs)];
|
|
189
|
+
const zs = Array.from(new Set(xs));
|
|
190
|
+
`,
|
|
191
|
+
output: dedent`
|
|
192
|
+
import { Arr } from 'ts-data-forge';
|
|
193
|
+
const xs = ['a', 'b'];
|
|
194
|
+
const ys = Arr.uniq(xs);
|
|
195
|
+
const zs = Arr.uniq(xs);
|
|
196
|
+
`,
|
|
197
|
+
errors: [{ messageId: 'useArrUniq' }, { messageId: 'useArrUniq' }],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: 'accepts tuples, literal unions, nullish and inline arrays',
|
|
201
|
+
code: dedent`
|
|
202
|
+
const t = [1, 'a', 1] as const;
|
|
203
|
+
const u: readonly ('x' | 'y' | null | undefined | boolean | bigint)[] = [];
|
|
204
|
+
const a = [...new Set(t)];
|
|
205
|
+
const b = [...new Set(u)];
|
|
206
|
+
const c = Array.from(new Set([1, 2, 1]));
|
|
207
|
+
`,
|
|
208
|
+
output: dedent`
|
|
209
|
+
import { Arr } from 'ts-data-forge';
|
|
210
|
+
const t = [1, 'a', 1] as const;
|
|
211
|
+
const u: readonly ('x' | 'y' | null | undefined | boolean | bigint)[] = [];
|
|
212
|
+
const a = Arr.uniq(t);
|
|
213
|
+
const b = Arr.uniq(u);
|
|
214
|
+
const c = Arr.uniq([1, 2, 1]);
|
|
215
|
+
`,
|
|
216
|
+
errors: [
|
|
217
|
+
{ messageId: 'useArrUniq' },
|
|
218
|
+
{ messageId: 'useArrUniq' },
|
|
219
|
+
{ messageId: 'useArrUniq' },
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: 'accepts a type parameter constrained to a primitive array',
|
|
224
|
+
code: dedent`
|
|
225
|
+
export const f = <T extends readonly string[]>(xs: T): readonly string[] =>
|
|
226
|
+
[...new Set(xs)];
|
|
227
|
+
`,
|
|
228
|
+
output: dedent`
|
|
229
|
+
import { Arr } from 'ts-data-forge';
|
|
230
|
+
export const f = <T extends readonly string[]>(xs: T): readonly string[] =>
|
|
231
|
+
Arr.uniq(xs);
|
|
232
|
+
`,
|
|
233
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'accepts an intersection with a primitive array',
|
|
237
|
+
code: dedent`
|
|
238
|
+
type Branded = readonly string[] & Readonly<{ brand: 'b' }>;
|
|
239
|
+
declare const xs: Branded;
|
|
240
|
+
const ys: readonly string[] = [...new Set(xs)];
|
|
241
|
+
`,
|
|
242
|
+
output: dedent`
|
|
243
|
+
import { Arr } from 'ts-data-forge';
|
|
244
|
+
type Branded = readonly string[] & Readonly<{ brand: 'b' }>;
|
|
245
|
+
declare const xs: Branded;
|
|
246
|
+
const ys: readonly string[] = Arr.uniq(xs);
|
|
247
|
+
`,
|
|
248
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'accepts a readonly array parameter',
|
|
252
|
+
code: dedent`
|
|
253
|
+
const g = (xs: readonly number[]): number => xs.length;
|
|
254
|
+
const xs = [1, 1];
|
|
255
|
+
const n = g([...new Set(xs)]);
|
|
256
|
+
`,
|
|
257
|
+
output: dedent`
|
|
258
|
+
import { Arr } from 'ts-data-forge';
|
|
259
|
+
const g = (xs: readonly number[]): number => xs.length;
|
|
260
|
+
const xs = [1, 1];
|
|
261
|
+
const n = g(Arr.uniq(xs));
|
|
262
|
+
`,
|
|
263
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: 'fixes an argument to a generic function taking a readonly array',
|
|
267
|
+
code: dedent`
|
|
268
|
+
const sorted = <const Ar extends readonly unknown[]>(xs: Ar): Ar => xs;
|
|
269
|
+
const xs = ['b', 'a', 'b'];
|
|
270
|
+
const ys = sorted(Array.from(new Set(xs)));
|
|
271
|
+
`,
|
|
272
|
+
output: dedent`
|
|
273
|
+
import { Arr } from 'ts-data-forge';
|
|
274
|
+
const sorted = <const Ar extends readonly unknown[]>(xs: Ar): Ar => xs;
|
|
275
|
+
const xs = ['b', 'a', 'b'];
|
|
276
|
+
const ys = sorted(Arr.uniq(xs));
|
|
277
|
+
`,
|
|
278
|
+
errors: [{ messageId: 'useArrUniq' }],
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: 'only suggests when the result is sorted in place',
|
|
282
|
+
code: dedent`
|
|
283
|
+
const xs = [3, 1, 3];
|
|
284
|
+
const ys = [...new Set(xs)].sort();
|
|
285
|
+
`,
|
|
286
|
+
output: null,
|
|
287
|
+
errors: [
|
|
288
|
+
{
|
|
289
|
+
messageId: 'useArrUniq',
|
|
290
|
+
suggestions: [
|
|
291
|
+
{
|
|
292
|
+
messageId: 'suggestArrUniq',
|
|
293
|
+
output: dedent`
|
|
294
|
+
import { Arr } from 'ts-data-forge';
|
|
295
|
+
const xs = [3, 1, 3];
|
|
296
|
+
const ys = Arr.uniq(xs).sort();
|
|
297
|
+
`,
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: 'only suggests when a variable holding the result is mutated',
|
|
305
|
+
code: dedent`
|
|
306
|
+
const xs = [3, 1, 3];
|
|
307
|
+
const ys = Array.from(new Set(xs));
|
|
308
|
+
ys.push(4);
|
|
309
|
+
`,
|
|
310
|
+
output: null,
|
|
311
|
+
errors: [
|
|
312
|
+
{
|
|
313
|
+
messageId: 'useArrUniq',
|
|
314
|
+
suggestions: [
|
|
315
|
+
{
|
|
316
|
+
messageId: 'suggestArrUniq',
|
|
317
|
+
output: dedent`
|
|
318
|
+
import { Arr } from 'ts-data-forge';
|
|
319
|
+
const xs = [3, 1, 3];
|
|
320
|
+
const ys = Arr.uniq(xs);
|
|
321
|
+
ys.push(4);
|
|
322
|
+
`,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: 'only suggests when an element of the result is assigned',
|
|
330
|
+
code: dedent`
|
|
331
|
+
const xs = [3, 1, 3];
|
|
332
|
+
const ys = [...new Set(xs)];
|
|
333
|
+
ys[0] = 2;
|
|
334
|
+
`,
|
|
335
|
+
output: null,
|
|
336
|
+
errors: [
|
|
337
|
+
{
|
|
338
|
+
messageId: 'useArrUniq',
|
|
339
|
+
suggestions: [
|
|
340
|
+
{
|
|
341
|
+
messageId: 'suggestArrUniq',
|
|
342
|
+
output: dedent`
|
|
343
|
+
import { Arr } from 'ts-data-forge';
|
|
344
|
+
const xs = [3, 1, 3];
|
|
345
|
+
const ys = Arr.uniq(xs);
|
|
346
|
+
ys[0] = 2;
|
|
347
|
+
`,
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: 'only suggests when a mutable array is expected',
|
|
355
|
+
code: dedent`
|
|
356
|
+
const h = (xs: number[]): number => xs.length;
|
|
357
|
+
const xs = [1, 1];
|
|
358
|
+
const n = h([...new Set(xs)]);
|
|
359
|
+
const m: number[] | undefined = Array.from(new Set(xs));
|
|
360
|
+
`,
|
|
361
|
+
output: null,
|
|
362
|
+
errors: [
|
|
363
|
+
{
|
|
364
|
+
messageId: 'useArrUniq',
|
|
365
|
+
suggestions: [
|
|
366
|
+
{
|
|
367
|
+
messageId: 'suggestArrUniq',
|
|
368
|
+
output: dedent`
|
|
369
|
+
import { Arr } from 'ts-data-forge';
|
|
370
|
+
const h = (xs: number[]): number => xs.length;
|
|
371
|
+
const xs = [1, 1];
|
|
372
|
+
const n = h(Arr.uniq(xs));
|
|
373
|
+
const m: number[] | undefined = Array.from(new Set(xs));
|
|
374
|
+
`,
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
messageId: 'useArrUniq',
|
|
380
|
+
suggestions: [
|
|
381
|
+
{
|
|
382
|
+
messageId: 'suggestArrUniq',
|
|
383
|
+
output: dedent`
|
|
384
|
+
import { Arr } from 'ts-data-forge';
|
|
385
|
+
const h = (xs: number[]): number => xs.length;
|
|
386
|
+
const xs = [1, 1];
|
|
387
|
+
const n = h([...new Set(xs)]);
|
|
388
|
+
const m: number[] | undefined = Arr.uniq(xs);
|
|
389
|
+
`,
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: 'only suggests when a variable holding the result is passed as a mutable array',
|
|
397
|
+
code: dedent`
|
|
398
|
+
const h = (xs: string[]): number => xs.length;
|
|
399
|
+
const xs = ['a'];
|
|
400
|
+
const ys = [...new Set(xs)];
|
|
401
|
+
const n = h(ys);
|
|
402
|
+
`,
|
|
403
|
+
output: null,
|
|
404
|
+
errors: [
|
|
405
|
+
{
|
|
406
|
+
messageId: 'useArrUniq',
|
|
407
|
+
suggestions: [
|
|
408
|
+
{
|
|
409
|
+
messageId: 'suggestArrUniq',
|
|
410
|
+
output: dedent`
|
|
411
|
+
import { Arr } from 'ts-data-forge';
|
|
412
|
+
const h = (xs: string[]): number => xs.length;
|
|
413
|
+
const xs = ['a'];
|
|
414
|
+
const ys = Arr.uniq(xs);
|
|
415
|
+
const n = h(ys);
|
|
416
|
+
`,
|
|
417
|
+
},
|
|
418
|
+
],
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
name: 'fixes the autofixable matches and suggests the rest',
|
|
424
|
+
code: dedent`
|
|
425
|
+
const xs = [3, 1, 3];
|
|
426
|
+
const a = [...new Set(xs)].sort();
|
|
427
|
+
const b = [...new Set(xs)];
|
|
428
|
+
`,
|
|
429
|
+
output: dedent`
|
|
430
|
+
import { Arr } from 'ts-data-forge';
|
|
431
|
+
const xs = [3, 1, 3];
|
|
432
|
+
const a = [...new Set(xs)].sort();
|
|
433
|
+
const b = Arr.uniq(xs);
|
|
434
|
+
`,
|
|
435
|
+
errors: [
|
|
436
|
+
{
|
|
437
|
+
messageId: 'useArrUniq',
|
|
438
|
+
suggestions: [
|
|
439
|
+
{
|
|
440
|
+
messageId: 'suggestArrUniq',
|
|
441
|
+
output: dedent`
|
|
442
|
+
import { Arr } from 'ts-data-forge';
|
|
443
|
+
const xs = [3, 1, 3];
|
|
444
|
+
const a = Arr.uniq(xs).sort();
|
|
445
|
+
const b = [...new Set(xs)];
|
|
446
|
+
`,
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
},
|
|
450
|
+
{ messageId: 'useArrUniq' },
|
|
451
|
+
],
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
});
|
|
455
|
+
});
|
package/src/rules/rules.mts
CHANGED
|
@@ -4,6 +4,7 @@ import { noUnnecessaryTypeGuard } from './no-unnecessary-type-guard.mjs';
|
|
|
4
4
|
import { preferArrIsArray } from './prefer-arr-is-array.mjs';
|
|
5
5
|
import { preferArrScan } from './prefer-arr-scan.mjs';
|
|
6
6
|
import { preferArrSum } from './prefer-arr-sum.mjs';
|
|
7
|
+
import { preferArrUniq } from './prefer-arr-uniq.mjs';
|
|
7
8
|
import { preferAsInt } from './prefer-as-int.mjs';
|
|
8
9
|
import { preferCanonicalArraySlicing } from './prefer-canonical-array-slicing.mjs';
|
|
9
10
|
import { preferCanonicalLengthCast } from './prefer-canonical-length-cast.mjs';
|
|
@@ -23,6 +24,7 @@ export const tsDataForgeRules = {
|
|
|
23
24
|
'prefer-arr-is-array': preferArrIsArray,
|
|
24
25
|
'prefer-arr-scan': preferArrScan,
|
|
25
26
|
'prefer-arr-sum': preferArrSum,
|
|
27
|
+
'prefer-arr-uniq': preferArrUniq,
|
|
26
28
|
'prefer-as-int': preferAsInt,
|
|
27
29
|
'prefer-is-non-null-object': preferIsNonNullObject,
|
|
28
30
|
'prefer-range-for-loop': preferRangeForLoop,
|