@data-client/rest 0.1.0 → 0.2.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.
Files changed (65) hide show
  1. package/dist/index.js +10 -14
  2. package/dist/index.umd.min.js +1 -1
  3. package/legacy/OptionsToFunction.js +1 -1
  4. package/legacy/RestEndpoint.js +5 -5
  5. package/legacy/createResource.js +8 -10
  6. package/legacy/index.js +2 -1
  7. package/legacy/next/index.js +4 -4
  8. package/legacy/resourceTypes.js +2 -0
  9. package/lib/OptionsToFunction.d.ts.map +1 -1
  10. package/lib/OptionsToFunction.js +1 -1
  11. package/lib/RestEndpoint.d.ts +29 -35
  12. package/lib/RestEndpoint.js +5 -5
  13. package/lib/createResource.d.ts +51 -31
  14. package/lib/createResource.d.ts.map +1 -1
  15. package/lib/createResource.js +7 -11
  16. package/lib/index.d.ts +3 -1
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +2 -1
  19. package/lib/next/index.d.ts +5 -5
  20. package/lib/next/index.d.ts.map +1 -1
  21. package/lib/next/index.js +4 -4
  22. package/lib/resourceTypes.d.ts.map +1 -0
  23. package/lib/resourceTypes.js +2 -0
  24. package/package.json +3 -3
  25. package/src/OptionsToFunction.ts +0 -1
  26. package/src/RestEndpoint.d.ts +29 -35
  27. package/src/RestEndpoint.js +4 -4
  28. package/src/__tests__/RestEndpoint.ts +38 -9
  29. package/src/__tests__/createResource.test.ts +3 -4
  30. package/src/__tests__/hookifyResource.ts +7 -3
  31. package/src/__tests__/types.test.ts +332 -212
  32. package/src/createResource.ts +81 -60
  33. package/src/index.ts +2 -2
  34. package/src/next/index.ts +5 -5
  35. package/ts4.0/RestEndpoint.d.ts +18 -32
  36. package/ts4.0/createResource.d.ts +59 -31
  37. package/ts4.0/index.d.ts +3 -1
  38. package/ts4.0/next/index.d.ts +5 -5
  39. package/legacy/next/OptionsToFunction.js +0 -2
  40. package/legacy/next/RestEndpoint.js +0 -225
  41. package/legacy/next/createResource.js +0 -86
  42. package/legacy/next/resourceTypes.js +0 -2
  43. package/lib/next/OptionsToFunction.d.ts +0 -7
  44. package/lib/next/OptionsToFunction.d.ts.map +0 -1
  45. package/lib/next/OptionsToFunction.js +0 -2
  46. package/lib/next/RestEndpoint.d.ts +0 -542
  47. package/lib/next/RestEndpoint.js +0 -229
  48. package/lib/next/createResource.d.ts +0 -86
  49. package/lib/next/createResource.d.ts.map +0 -1
  50. package/lib/next/createResource.js +0 -100
  51. package/lib/next/resourceTypes.d.ts.map +0 -1
  52. package/lib/next/resourceTypes.js +0 -2
  53. package/src/next/OptionsToFunction.ts +0 -41
  54. package/src/next/RestEndpoint.d.ts +0 -542
  55. package/src/next/RestEndpoint.js +0 -262
  56. package/src/next/__tests__/RestEndpoint.ts +0 -1333
  57. package/src/next/__tests__/__snapshots__/RestEndpoint.ts.snap +0 -18
  58. package/src/next/__tests__/types.test.ts +0 -429
  59. package/src/next/createResource.ts +0 -194
  60. package/ts4.0/next/OptionsToFunction.d.ts +0 -16
  61. package/ts4.0/next/RestEndpoint.d.ts +0 -226
  62. package/ts4.0/next/createResource.d.ts +0 -94
  63. /package/lib/{next/resourceTypes.d.ts → resourceTypes.d.ts} +0 -0
  64. /package/src/{next/resourceTypes.ts → resourceTypes.ts} +0 -0
  65. /package/ts4.0/{next/resourceTypes.d.ts → resourceTypes.d.ts} +0 -0
@@ -1,205 +1,10 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
1
2
  import { Entity, schema } from '@data-client/endpoint';
3
+ import { useSuspense } from '@data-client/react';
2
4
  import { User } from '__tests__/new';
3
5
 
4
6
  import createResource from '../createResource';
5
- import {
6
- KeysToArgs,
7
- PathArgs,
8
- PathArgsAndSearch,
9
- PathKeys,
10
- ShortenPath,
11
- } from '../pathTypes';
12
- import RestEndpoint, { GetEndpoint, NewGetEndpoint } from '../RestEndpoint';
13
- import { RequiredKeys } from '../utiltypes';
14
-
15
- describe('PathArgs', () => {
16
- it('should infer types', () => {
17
- type C =
18
- 'http\\://test.com/groups/:group?/\\:blah/users/:id?:extra?/:next\\?bob/:last';
19
- function A(args: PathArgs<C>) {}
20
- // @ts-expect-error
21
- () => A({});
22
- () => A({ next: 'hi', last: 'ho' });
23
- // @ts-expect-error
24
- () => A({ next: 'hi', last: 'ho', doesnotexist: 'hi' });
25
- // @ts-expect-error
26
- () => A({ next: 'hi', last: 'ho', blah: 'hi' });
27
- () => A({ next: 'hi', last: 'ho', id: '5', group: 'whatever' });
28
- () => A({ next: 'hi', last: 'ho', extra: '5', group: 'whatever' });
29
- });
30
-
31
- it('should infer types2', () => {
32
- type C = 'http\\://test.com/article-cooler/:id?:title?';
33
- function A(args: PathArgs<C>) {}
34
- () => A({});
35
- () => A({ id: 'ho' });
36
- () => A({ title: 'ho' });
37
- () => A({ id: 'ho', title: 'ho' });
38
- // @ts-expect-error
39
- () => A({ idasd: 'ho' });
40
- // @ts-expect-error
41
- () => A({ next: 'hi', title: 'ho', id: 'hi' });
42
- // @ts-expect-error
43
- () => A(5);
44
- });
45
-
46
- it('should infer types with other characters to stop', () => {
47
- type C = 'http\\://test.com/search/issues?q=:q?%20repo\\::owner/:repo';
48
- function A(args: PathArgs<C>) {}
49
- () => A({ owner: 'data-client', repo: 'data-client' });
50
- () => A({ owner: 'data-client', repo: 'data-client', q: 'is:issue' });
51
- // @ts-expect-error
52
- () => A({ idasd: 'ho' });
53
- // @ts-expect-error
54
- () => A({ owner: 'data-client', repo: 'data-client', extra: 'is:issue' });
55
- // @ts-expect-error
56
- () => A({ owner: 'data-client' });
57
- // @ts-expect-error
58
- () => A(5);
59
- });
60
-
61
- it('should be flexible for string type', () => {
62
- class Parent {
63
- constructor() {}
64
- A(args: PathArgs<string>) {
65
- const b = args['hi'];
66
- }
67
- }
68
- class Child extends Parent {
69
- A(args: { item: string }) {}
70
- }
71
- const thing = new Parent();
72
- () => thing.A({});
73
- () => thing.A({ next: 'hi', last: 'ho' });
74
- const thing2 = new Child();
75
- //@ts-expect-error
76
- () => thing2.A({});
77
- () => thing2.A({ item: 'win' });
78
- });
79
-
80
- it('works with no arguments', () => {
81
- const a: GetEndpoint<PathArgs<'http\\://test.com/article-cooler/'>> =
82
- 0 as any;
83
- () => a();
84
- //@ts-expect-error
85
- () => a({ page: '5' });
86
- //@ts-expect-error
87
- () => a({ sdf: '5' });
88
- //@ts-expect-error
89
- () => a(5);
90
- });
91
-
92
- it('works when combining with known types', () => {
93
- const a: GetEndpoint<
94
- PathArgs<ShortenPath<'/hi'>> & { page: string | number }
95
- > = 0 as any;
96
- () => a({ page: '5' });
97
- //@ts-expect-error
98
- () => a({ sdf: '5' });
99
- //@ts-expect-error
100
- () => a({ page: '5' }, { hi: '5' });
101
- //@ts-expect-error
102
- () => a();
103
- });
104
-
105
- it('works with unions of non-intersecting types', () => {
106
- const a: GetEndpoint<{ id: string | number } | { title: string | number }> =
107
- 0 as any;
108
- () => a({ id: '5' });
109
- () => a({ title: '5' });
110
- // @ts-expect-error
111
- () => a({ id: '5', title: '5' });
112
- // @ts-expect-error
113
- () => a({ id: '5', sdfds: '5' });
114
- //@ts-expect-error
115
- () => a({ sdf: '5' });
116
- //@ts-expect-error
117
- () => a({ page: '5' }, { hi: '5' });
118
- //@ts-expect-error
119
- () => a();
120
- });
121
-
122
- it('works with optional positional args', () => {
123
- const a: GetEndpoint<undefined | { cursor?: string | number }> = 0 as any;
124
- () => a();
125
- () => a({});
126
- () => a({ cursor: 5 });
127
- // @ts-expect-error
128
- () => a({ id: '5' });
129
- //@ts-expect-error
130
- () => a({ cursor: '5' }, { cursor: '5' });
131
- });
132
-
133
- it('searchParams', () => {
134
- const a: GetEndpoint<undefined | { cursor?: string | number }> = 0 as any;
135
- () => a();
136
- () => a({});
137
- () => a({ cursor: 5 });
138
- // @ts-expect-error
139
- () => a({ id: '5' });
140
- //@ts-expect-error
141
- () => a({ cursor: '5' }, { cursor: '5' });
142
- });
143
-
144
- describe('PathArgsAndSearch', () => {
145
- it('works with required path member', () => {
146
- const a: GetEndpoint<
147
- PathArgsAndSearch<'http\\://test.com/groups/:group/users/'>
148
- > = 0 as any;
149
- () => a({ group: '5' });
150
- () => a({ group: '5', sdf: '5' });
151
- //@ts-expect-error
152
- () => a({ asdf: '5' });
153
- //@ts-expect-error
154
- () => a({});
155
- //@ts-expect-error
156
- () => a({ page: '5' }, { hi: '5' });
157
- //@ts-expect-error
158
- () => a();
159
- });
160
- it('works with no path members', () => {
161
- const a: NewGetEndpoint<{
162
- path: 'http\\://test.com/groups';
163
- searchParams: Record<string, number | string | boolean> | undefined;
164
- }> = 0 as any;
165
- /*const a: GetEndpoint<PathArgsAndSearch<'http\\://test.com/groups/'>> =
166
- 0 as any;*/
167
- () => a({ group: '5' });
168
- () => a({ group: '5', sdf: '5' });
169
- () => a();
170
- () => a({ asdf: '5' });
171
- () => a({});
172
- //@ts-expect-error
173
- () => a({ page: '5' }, { hi: '5' });
174
-
175
- () => {
176
- const b = a.extend({
177
- searchParams: {} as { userId?: number | string } | undefined,
178
- });
179
- b({ userId: '5' });
180
- b();
181
- // @ts-expect-error
182
- b({ sdf: '5' });
183
- };
184
- });
185
- });
186
- });
187
-
188
- describe('RequiredKeys', () => {
189
- type Y = {
190
- opt?: string;
191
- bob: string;
192
- charles: number;
193
- [k: string]: string | number | undefined;
194
- };
195
- const a: Record<RequiredKeys<Y>, any> = 5 as any;
196
- () => a.bob;
197
- () => a.charles;
198
- // @ts-expect-error
199
- () => a.opt;
200
- // @ts-expect-error
201
- () => a.sdfsdf;
202
- });
7
+ import RestEndpoint, { MutateEndpoint } from '../RestEndpoint';
203
8
 
204
9
  it('RestEndpoint construct and extend with typed options', () => {
205
10
  new RestEndpoint({
@@ -282,28 +87,343 @@ it('should customize resources', () => {
282
87
  }
283
88
  }
284
89
 
285
- const TodoResourceBase = createResource({
90
+ const TodoResource = createResource({
286
91
  path: '/todos/:id',
287
92
  schema: Todo,
288
93
  });
289
- TodoResourceBase.create.extend({
94
+ TodoResource.create.extend({
95
+ searchParams: {} as { userId?: string | number } | undefined,
96
+ getOptimisticResponse(snap, ...args) {
97
+ return args[args.length - 1];
98
+ },
99
+ });
100
+ const partial = TodoResource.partialUpdate.extend({
101
+ getOptimisticResponse(snap, { id }, body) {
102
+ return {
103
+ id,
104
+ ...body,
105
+ };
106
+ },
107
+ });
108
+ () => partial({ id: 5 }, { title: 'hi' });
109
+ const a: MutateEndpoint<{
110
+ path: '/todos/';
111
+ body: Partial<Todo>;
112
+ schema: typeof Todo;
113
+ }> = TodoResource.create.extend({ schema: Todo }) as any;
114
+ a.extend({
290
115
  searchParams: {} as { userId?: string | number } | undefined,
291
116
  getOptimisticResponse(snap, ...args) {
292
117
  return args[args.length - 1];
293
118
  },
294
119
  });
295
- TodoResourceBase.create
296
- .extend({
297
- schema: new schema.Collection([Todo], {
298
- argsKey(...args) {
299
- return { a: 5 };
300
- },
301
- }),
302
- })
303
- .extend({
304
- searchParams: {} as { userId?: string | number } | undefined,
305
- getOptimisticResponse(snap, ...args) {
306
- return args[args.length - 1];
120
+
121
+ () => useSuspense(TodoResource.getList);
122
+ });
123
+
124
+ // path: ['/todos', '/todos/:id', '/todos/:id?', string]
125
+ it('should precisely type function arguments', () => {
126
+ // path: '/todos'
127
+ () => {
128
+ const optionalUndefSearch = new RestEndpoint({
129
+ path: '/todos',
130
+ searchParams: {} as
131
+ | {
132
+ userId?: string | number;
133
+ }
134
+ | undefined,
135
+ });
136
+ const optionalSearch = new RestEndpoint({
137
+ path: '/todos',
138
+ searchParams: {} as {
139
+ userId?: string | number;
307
140
  },
308
141
  });
142
+ const undef = new RestEndpoint({
143
+ path: '/todos',
144
+ searchParams: undefined,
145
+ });
146
+ const requiredSearch = new RestEndpoint({
147
+ path: '/todos',
148
+ searchParams: {} as {
149
+ userId: string | number;
150
+ },
151
+ });
152
+ const noSearch = new RestEndpoint({
153
+ path: '/todos',
154
+ });
155
+ () => optionalUndefSearch();
156
+ () => optionalUndefSearch({});
157
+ () => optionalUndefSearch({ userId: 'hi' });
158
+ // @ts-expect-error
159
+ () => optionalUndefSearch(5);
160
+ // @ts-expect-error
161
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
162
+
163
+ () => optionalSearch();
164
+ () => optionalSearch({});
165
+ () => optionalSearch({ userId: 'hi' });
166
+ // @ts-expect-error
167
+ () => optionalSearch(5);
168
+ // @ts-expect-error
169
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
170
+
171
+ // @ts-expect-error
172
+ () => requiredSearch();
173
+ // @ts-expect-error
174
+ () => requiredSearch({});
175
+ () => requiredSearch({ userId: 'hi' });
176
+ // @ts-expect-error
177
+ () => requiredSearch(5);
178
+ // @ts-expect-error
179
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
180
+
181
+ () => undef();
182
+ // @ts-expect-error
183
+ () => undef({});
184
+ // @ts-expect-error
185
+ () => undef({ userId: 'hi' });
186
+ // @ts-expect-error
187
+ () => undef(5);
188
+
189
+ () => noSearch();
190
+ // @ts-expect-error
191
+ () => noSearch({});
192
+ // @ts-expect-error
193
+ () => noSearch({ userId: 'hi' });
194
+ // @ts-expect-error
195
+ () => noSearch(5);
196
+ };
197
+ // path: '/todos/:id?'
198
+ () => {
199
+ const optionalUndefSearch = new RestEndpoint({
200
+ path: '/todos/:id?',
201
+ searchParams: {} as
202
+ | {
203
+ userId?: string | number;
204
+ }
205
+ | undefined,
206
+ });
207
+ const optionalSearch = new RestEndpoint({
208
+ path: '/todos/:id?',
209
+ searchParams: {} as {
210
+ userId?: string | number;
211
+ },
212
+ });
213
+ const undef = new RestEndpoint({
214
+ path: '/todos/:id?',
215
+ searchParams: undefined,
216
+ });
217
+ const requiredSearch = new RestEndpoint({
218
+ path: '/todos/:id?',
219
+ searchParams: {} as {
220
+ userId: string | number;
221
+ },
222
+ });
223
+ const noSearch = new RestEndpoint({
224
+ path: '/todos/:id?',
225
+ });
226
+ () => optionalUndefSearch();
227
+ () => optionalUndefSearch({});
228
+ () => optionalUndefSearch({ id: '5' });
229
+ () => optionalUndefSearch({ userId: 'hi' });
230
+ () => optionalUndefSearch({ userId: 'hi', id: '5' });
231
+ // @ts-expect-error
232
+ () => optionalUndefSearch(5);
233
+ // @ts-expect-error
234
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
235
+
236
+ () => optionalSearch();
237
+ () => optionalSearch({});
238
+ () => optionalSearch({ id: '5' });
239
+ () => optionalSearch({ userId: 'hi' });
240
+ () => optionalSearch({ userId: 'hi', id: '5' });
241
+ // @ts-expect-error
242
+ () => optionalSearch(5);
243
+ // @ts-expect-error
244
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
245
+
246
+ // @ts-expect-error
247
+ () => requiredSearch();
248
+ // @ts-expect-error
249
+ () => requiredSearch({});
250
+ // @ts-expect-error
251
+ () => requiredSearch({ id: '5' });
252
+ () => requiredSearch({ userId: 'hi' });
253
+ () => requiredSearch({ userId: 'hi', id: '5' });
254
+ // @ts-expect-error
255
+ () => requiredSearch(5);
256
+ // @ts-expect-error
257
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
258
+
259
+ () => undef();
260
+ // @ts-ignore TODO
261
+ () => undef({});
262
+ // @ts-ignore TODO
263
+ () => undef({ id: '5' });
264
+ // @ts-expect-error
265
+ () => undef({ userId: 'hi' });
266
+ // @ts-expect-error
267
+ () => undef(5);
268
+
269
+ () => noSearch();
270
+ () => noSearch({});
271
+ () => noSearch({ id: '5' });
272
+ // @ts-expect-error
273
+ () => noSearch({ userId: 'hi' });
274
+ // @ts-expect-error
275
+ () => noSearch(5);
276
+ };
277
+ // path: '/todos/:id'
278
+ () => {
279
+ const optionalUndefSearch = new RestEndpoint({
280
+ path: '/todos/:id',
281
+ searchParams: {} as
282
+ | {
283
+ userId?: string | number;
284
+ }
285
+ | undefined,
286
+ });
287
+ const optionalSearch = new RestEndpoint({
288
+ path: '/todos/:id',
289
+ searchParams: {} as {
290
+ userId?: string | number;
291
+ },
292
+ });
293
+ const undef = new RestEndpoint({
294
+ path: '/todos/:id',
295
+ searchParams: undefined,
296
+ });
297
+ const requiredSearch = new RestEndpoint({
298
+ path: '/todos/:id',
299
+ searchParams: {} as {
300
+ userId: string | number;
301
+ },
302
+ });
303
+ const noSearch = new RestEndpoint({
304
+ path: '/todos/:id',
305
+ });
306
+ // @ts-expect-error
307
+ () => optionalUndefSearch();
308
+ () => optionalUndefSearch({ id: '5' });
309
+ () => optionalUndefSearch({ id: '5', userId: 'hi' });
310
+ // @ts-expect-error
311
+ () => optionalUndefSearch(5);
312
+ () =>
313
+ // @ts-expect-error
314
+ optionalUndefSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
315
+
316
+ // @ts-expect-error
317
+ () => optionalSearch();
318
+ () => optionalSearch({ id: '5' });
319
+ () => optionalSearch({ id: '5', userId: 'hi' });
320
+ // @ts-expect-error
321
+ () => optionalSearch(5);
322
+ // @ts-expect-error
323
+ () => optionalSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
324
+
325
+ // @ts-expect-error
326
+ () => requiredSearch();
327
+ // @ts-expect-error
328
+ () => requiredSearch({ id: '5' });
329
+ () => requiredSearch({ id: '5', userId: 'hi' });
330
+ // @ts-expect-error
331
+ () => requiredSearch(5);
332
+ // @ts-expect-error
333
+ () => requiredSearch({ id: '5', userId: 'hi' }, { id: '5', userId: 'hi' });
334
+
335
+ // @ts-expect-error
336
+ () => undef();
337
+ // @ts-expect-error
338
+ () => undef({});
339
+ // @ts-expect-error
340
+ () => undef({ id: '5', userId: 'hi' });
341
+ // @ts-expect-error
342
+ () => undef(5);
343
+
344
+ // @ts-expect-error
345
+ () => noSearch();
346
+ () => noSearch({ id: '5' });
347
+ // @ts-expect-error
348
+ () => noSearch({ id: '5', userId: 'hi' });
349
+ // @ts-expect-error
350
+ () => noSearch(5);
351
+ };
352
+ // path: string
353
+ () => {
354
+ const optionalUndefSearch = new RestEndpoint({
355
+ path: '' as string,
356
+ searchParams: {} as
357
+ | {
358
+ userId?: string | number;
359
+ }
360
+ | undefined,
361
+ });
362
+ const optionalSearch = new RestEndpoint({
363
+ path: '' as string,
364
+ searchParams: {} as {
365
+ userId?: string | number;
366
+ },
367
+ });
368
+ const undef = new RestEndpoint({
369
+ path: '' as string,
370
+ searchParams: undefined,
371
+ });
372
+ const requiredSearch = new RestEndpoint({
373
+ path: '' as string,
374
+ searchParams: {} as {
375
+ userId: string | number;
376
+ },
377
+ });
378
+ const noSearch = new RestEndpoint({
379
+ path: '' as string,
380
+ });
381
+ () => optionalUndefSearch();
382
+ () => optionalUndefSearch({});
383
+ () => optionalUndefSearch({ id: '5' });
384
+ () => optionalUndefSearch({ userId: 'hi' });
385
+ () => optionalUndefSearch({ userId: 'hi', id: '5' });
386
+ // @ts-expect-error
387
+ () => optionalUndefSearch(5);
388
+ // @ts-expect-error
389
+ () => optionalUndefSearch({ userId: 'hi' }, { userId: 'hi' });
390
+
391
+ () => optionalSearch();
392
+ () => optionalSearch({});
393
+ () => optionalSearch({ id: '5' });
394
+ () => optionalSearch({ userId: 'hi' });
395
+ () => optionalSearch({ userId: 'hi', id: '5' });
396
+ // @ts-expect-error
397
+ () => optionalSearch(5);
398
+ // @ts-expect-error
399
+ () => optionalSearch({ userId: 'hi' }, { userId: 'hi' });
400
+
401
+ // @ts-expect-error
402
+ () => requiredSearch();
403
+ // @ts-expect-error
404
+ () => requiredSearch({});
405
+ // @ts-expect-error
406
+ () => requiredSearch({ id: '5' });
407
+ () => requiredSearch({ userId: 'hi' });
408
+ () => requiredSearch({ userId: 'hi', id: '5' });
409
+ // @ts-expect-error
410
+ () => requiredSearch(5);
411
+ // @ts-expect-error
412
+ () => requiredSearch({ userId: 'hi' }, { userId: 'hi' });
413
+
414
+ () => undef();
415
+ // @ts-ignore TODO
416
+ () => undef({});
417
+ // @ts-ignore TODO
418
+ () => undef({ id: '5' });
419
+ // @ts-expect-error
420
+ () => undef(5);
421
+
422
+ () => noSearch();
423
+ () => noSearch({});
424
+ () => noSearch({ id: '5' });
425
+ () => noSearch({ userId: 'hi' });
426
+ // @ts-expect-error
427
+ () => noSearch(5);
428
+ };
309
429
  });