typia 5.5.0-dev.20240302 → 5.5.0-dev.20240303

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 (29) hide show
  1. package/lib/functional.d.ts +353 -0
  2. package/lib/functional.js +130 -0
  3. package/lib/functional.js.map +1 -0
  4. package/lib/module.d.ts +1 -0
  5. package/lib/module.js +2 -1
  6. package/lib/module.js.map +1 -1
  7. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.d.ts +6 -0
  8. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.js +33 -0
  9. package/lib/programmers/functional/FunctionalAssertFunctionProgrammer.js.map +1 -0
  10. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.d.ts +11 -0
  11. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.js +58 -0
  12. package/lib/programmers/functional/FunctionalAssertParametersProgrammer.js.map +1 -0
  13. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.d.ts +14 -0
  14. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.js +67 -0
  15. package/lib/programmers/functional/FunctionalAssertReturnProgrammer.js.map +1 -0
  16. package/lib/transformers/CallExpressionTransformer.d.ts +1 -1
  17. package/lib/transformers/CallExpressionTransformer.js +49 -0
  18. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  19. package/lib/transformers/features/functional/FunctionalGenericTransformer.d.ts +10 -0
  20. package/lib/transformers/features/functional/FunctionalGenericTransformer.js +32 -0
  21. package/lib/transformers/features/functional/FunctionalGenericTransformer.js.map +1 -0
  22. package/package.json +1 -1
  23. package/src/functional.ts +561 -0
  24. package/src/module.ts +1 -0
  25. package/src/programmers/functional/FunctionalAssertFunctionProgrammer.ts +44 -0
  26. package/src/programmers/functional/FunctionalAssertParametersProgrammer.ts +100 -0
  27. package/src/programmers/functional/FunctionalAssertReturnProgrammer.ts +84 -0
  28. package/src/transformers/CallExpressionTransformer.ts +52 -5
  29. package/src/transformers/features/functional/FunctionalGenericTransformer.ts +41 -0
@@ -0,0 +1,561 @@
1
+ import * as Namespace from "./functional/Namespace";
2
+ import { IValidation } from "./IValidation";
3
+
4
+ import { TypeGuardError } from "./TypeGuardError";
5
+
6
+ /* ===========================================================
7
+ FUNCTIONAL
8
+ - ASSERTIONS
9
+ - VALIDATIONS
10
+ ==============================================================
11
+ ASSERTIONS
12
+ ----------------------------------------------------------- */
13
+ /**
14
+ * Asserts a function.
15
+ *
16
+ * Asserts a function, by wrapping the function and checking its parameters and
17
+ * return value through {@link assert} function. If some parameter or return value
18
+ * does not match the expected type, it throws an {@link TypeGuardError} or a custom
19
+ * error generated by the *errorFactory* parameter.
20
+ *
21
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
22
+ * individual {@link assert} function. If the {@link TypeGuardError} occurs from
23
+ * some parameter, the path would start from `$input.parameters[number]`. Otherwise
24
+ * the path would start from `$input.return`.
25
+ *
26
+ * - `$input.parameters[0].~`
27
+ * - `$input.return.~`
28
+ *
29
+ * By the way, if what you want is not just finding the 1st type error through
30
+ * assertion, but also finding every type errors, then use {@link validateFunction}
31
+ * instead. Otherwise, what you want is just asserting parameters or return value
32
+ * only, you can use {@link assertParameters} or {@link assertReturn} instead.
33
+ *
34
+ * On the other hand, if don't want to allow any superfluous properties, utilize
35
+ * {@link assertEqualsFunction} or {@link validateEqualsFunction} instead.
36
+ *
37
+ * @template T Target function type
38
+ * @param func Target function to assert
39
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
40
+ * @returns The wrapper function with type assertions
41
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
42
+ *
43
+ * @author Jeongho Nam - https://github.com/samchon
44
+ */
45
+ function assertFunction<T extends (...args: unknown[]) => unknown>(
46
+ func: T,
47
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
48
+ ): T;
49
+
50
+ /**
51
+ * @internal
52
+ */
53
+ function assertFunction(): never {
54
+ halt("assertFunction");
55
+ }
56
+ const assertFunctionPure = /** @__PURE__ */ Object.assign<
57
+ typeof assertFunction,
58
+ {}
59
+ >(
60
+ assertFunction,
61
+ /** @__PURE__ */ Namespace.assert("functional.assertFunction"),
62
+ );
63
+ export { assertFunctionPure as assertFunction };
64
+
65
+ /**
66
+ * Asserts parameters.
67
+ *
68
+ * Asserts a function, by wrapping the function and checking its parameters through
69
+ * {@link assert} function. If some parameter does not match the expected type, it
70
+ * throws an {@link TypeGuardError} or a custom error generated by the *errorFactory*
71
+ * parameter.
72
+ *
73
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
74
+ * individual {@link assert} function. If the {@link TypeGuardError} occurs from
75
+ * some parameter, the path would start from `$input.parameters[number]`.
76
+ *
77
+ * By the way, if what you want is not just finding the 1st type error through
78
+ * assertion, but also finding every type errors, then use {@link validateParameters}
79
+ * instead. Otherwise, what you want is not only asserting parameters, but also
80
+ * asserting return value, you can use {@link assertFunction} instead.
81
+ *
82
+ * On the other hand, if don't want to allow any superfluous properties, utilize
83
+ * {@link assertEqualsParameters} or {@link validateEqualsParameters} instead.
84
+ *
85
+ * @template T Target function type
86
+ * @param func Target function to assert
87
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
88
+ * @returns The wrapper function with type assertions
89
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
90
+ *
91
+ * @author Jeongho Nam - https://github.com/samchon
92
+ */
93
+ function assertParameters<T extends (...args: unknown[]) => unknown>(
94
+ func: T,
95
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
96
+ ): T;
97
+
98
+ /**
99
+ * @internal
100
+ */
101
+ function assertParameters(): never {
102
+ halt("assertParameters");
103
+ }
104
+ const assertParametersPure = /** @__PURE__ */ Object.assign<
105
+ typeof assertParameters,
106
+ {}
107
+ >(
108
+ assertParameters,
109
+ /** @__PURE__ */ Namespace.assert("functional.assertParameters"),
110
+ );
111
+ export { assertParametersPure as assertParameters };
112
+
113
+ /**
114
+ * Asserts return value.
115
+ *
116
+ * Asserts a function, by wrapping the function and checking its return value through
117
+ * {@link assert} function. If the return value does not match the expected type, it
118
+ * throws an {@link TypeGuardError} or a custom error generated by the *errorFactory*
119
+ * parameter.
120
+ *
121
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
122
+ * individual {@link assert} function. If the {@link TypeGuardError} occurs from
123
+ * the return value, the path would start from `$input.return`.
124
+ *
125
+ * By the way, if what you want is not just finding the 1st type error through
126
+ * assertion, but also finding every type errors, then use {@link validateReturn}
127
+ * instead. Otherwise, what you want is not only asserting return value, but also
128
+ * asserting parameters, you can use {@link assertFunction} instead.
129
+ *
130
+ * On the other hand, if don't want to allow any superfluous properties, utilize
131
+ * {@link assertEqualsReturn} or {@link validateEqualsReturn} instead.
132
+ *
133
+ * @template T Target function type
134
+ * @param func Target function to assert
135
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
136
+ * @returns The wrapper function with type assertions
137
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
138
+ *
139
+ * @author Jeongho Nam - https://github.com/samchon
140
+ */
141
+ function assertReturn<T extends (...args: unknown[]) => unknown>(
142
+ func: T,
143
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
144
+ ): T;
145
+
146
+ /**
147
+ * @internal
148
+ */
149
+ function assertReturn(): never {
150
+ halt("assertReturn");
151
+ }
152
+ const assertReturnPure = /** @__PURE__ */ Object.assign<
153
+ typeof assertReturn,
154
+ {}
155
+ >(assertReturn, /** @__PURE__ */ Namespace.assert("functional.assertReturn"));
156
+ export { assertReturnPure as assertReturn };
157
+
158
+ /**
159
+ * Asserts a function with strict equality.
160
+ *
161
+ * Asserts a function with strict equality, by wrapping the function and checking
162
+ * its parameters and return value through {@link assertEquals} function. If some
163
+ * parameter or return value does not match the expected type, it throws an
164
+ * {@link TypeGuardError} or a custom error generated by the *errorFactory* parameter.
165
+ *
166
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
167
+ * individual {@link assertEquals} function. If the {@link TypeGuardError} occurs from
168
+ * some parameter, the path would start from `$input.parameters[number]`. Otherwise
169
+ * the path would start from `$input.return`.
170
+ *
171
+ * - `$input.parameters[0].~`
172
+ * - `$input.return.~`
173
+ *
174
+ * By the way, if what you want is not just finding the 1st type error through
175
+ * assertion, but also finding every type errors, then use
176
+ * {@link validateEqualsFunction} instead. Otherwise, what you want is just asserting
177
+ * parameters or return value only, you can use {@link assertEqualsParameters} or
178
+ * {@link assertEqualsReturn} instead.
179
+ *
180
+ * On the other hand, if you want to allow any superfluous properties, utilize
181
+ * {@link assertFunction} or {@link validateFunction} instead.
182
+ *
183
+ * @template T Target function type
184
+ * @param func Target function to assert
185
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
186
+ * @returns The wrapper function with type assertions
187
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
188
+ *
189
+ * @author Jeongho Nam - https://github.com/samchon
190
+ */
191
+ function assertEqualsFunction<T extends (...args: unknown[]) => unknown>(
192
+ func: T,
193
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
194
+ ): T;
195
+
196
+ /**
197
+ * @internal
198
+ */
199
+ function assertEqualsFunction(): never {
200
+ halt("assertEqualsFunction");
201
+ }
202
+ const assertEqualsFunctionPure = /** @__PURE__ */ Object.assign<
203
+ typeof assertEqualsFunction,
204
+ {}
205
+ >(
206
+ assertEqualsFunction,
207
+ /** @__PURE__ */ Namespace.assert("functional.assertEqualsFunction"),
208
+ );
209
+ export { assertEqualsFunctionPure as assertEqualsFunction };
210
+
211
+ /**
212
+ * Asserts parameters with strict equality.
213
+ *
214
+ * Asserts a function, by wrapping the function and checking its parameters through
215
+ * {@link assertEquals} function. If some parameter does not match the expected type,
216
+ * it throws an {@link TypeGuardError} or a custom error generated by the *errorFactory*
217
+ * parameter.
218
+ *
219
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
220
+ * individual {@link assertEquals} function. If the {@link TypeGuardError} occurs from
221
+ * some parameter, the path would start from `$input.parameters[number]`.
222
+ *
223
+ * By the way, if what you want is not just finding the 1st type error through
224
+ * assertion, but also finding every type errors, then use
225
+ * {@link validateEqualsParameters} instead. Otherwise, what you want is not only
226
+ * asserting parameters, but also asserting return value, you can use
227
+ * {@link assertEqualsFunction} instead.
228
+ *
229
+ * On the other hand, if you want to allow any superfluous properties, utilize
230
+ * {@link assertParameters} or {@link validateParameters} instead.
231
+ *
232
+ * @template T Target function type
233
+ * @param func Target function to assert
234
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
235
+ * @returns The wrapper function with type assertions
236
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
237
+ *
238
+ * @author Jeongho Nam - https://github.com/samchon
239
+ */
240
+ function assertEqualsParameters<T extends (...args: unknown[]) => unknown>(
241
+ func: T,
242
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
243
+ ): T;
244
+
245
+ /**
246
+ * @internal
247
+ */
248
+ function assertEqualsParameters(): never {
249
+ halt("assertEqualsParameters");
250
+ }
251
+ const assertEqualsParametersPure = /** @__PURE__ */ Object.assign<
252
+ typeof assertEqualsParameters,
253
+ {}
254
+ >(
255
+ assertEqualsParameters,
256
+ /** @__PURE__ */ Namespace.assert("functional.assertEqualsParameters"),
257
+ );
258
+ export { assertEqualsParametersPure as assertEqualsParameters };
259
+
260
+ /**
261
+ * Asserts return value with strict equality.
262
+ *
263
+ * Asserts a function, by wrapping the function and checking its return value through
264
+ * {@link assertEquals} function. If the return value does not match the expected type,
265
+ * it throws an {@link TypeGuardError} or a custom error generated by the *errorFactory*
266
+ * parameter.
267
+ *
268
+ * For reference, {@link TypeGuardError.path} would be a little bit different with
269
+ * individual {@link assertEquals} function. If the {@link TypeGuardError} occurs from
270
+ * the return value, the path would start from `$input.return`.
271
+ *
272
+ * By the way, if what you want is not just finding the 1st type error through
273
+ * assertion, but also finding every type errors, then use {@link validateEqualsReturn}
274
+ * instead. Otherwise, what you want is not only asserting return value, but also
275
+ * asserting parameters, you can use {@link assertEqualsFunction} instead.
276
+ *
277
+ * On the other hand, if you want to allow any superfluous properties, utilize
278
+ * {@link assertReturn} or {@link validateReturn} instead.
279
+ *
280
+ * @template T Target function type
281
+ * @param func Target function to assert
282
+ * @param errorFactory Custom error factory. Default is `TypeGuardError`
283
+ * @returns The wrapper function with type assertions
284
+ * @throws A {@link TypeGuardError} or a custom error generated by *errorFactory*
285
+ *
286
+ * @author Jeongho Nam - https://github.com/samchon
287
+ */
288
+ function assertEqualsReturn<T extends (...args: unknown[]) => unknown>(
289
+ func: T,
290
+ errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
291
+ ): T;
292
+
293
+ /**
294
+ * @internal
295
+ */
296
+ function assertEqualsReturn(): never {
297
+ halt("assertEqualsReturn");
298
+ }
299
+ const assertEqualsReturnPure = /** @__PURE__ */ Object.assign<
300
+ typeof assertEqualsReturn,
301
+ {}
302
+ >(
303
+ assertEqualsReturn,
304
+ /** @__PURE__ */ Namespace.assert("functional.assertEqualsReturn"),
305
+ );
306
+ export { assertEqualsReturnPure as assertEqualsReturn };
307
+
308
+ /* -----------------------------------------------------------
309
+ VALIDATIONS
310
+ ----------------------------------------------------------- */
311
+ /**
312
+ * Validates a function.
313
+ *
314
+ * Validates a function, by wrapping the function and checking its parameters and
315
+ * return value through {@link validate} function. If some parameter or return value
316
+ * does not match the expected type, it returns {@link IValidation.IError} typed
317
+ * object. Otherwise there's no type error, it returns {@link IValidation.ISuccess}
318
+ * typed object instead.
319
+ *
320
+ * For reference, {@link IValidation.IError.path} would be a little bit different with
321
+ * individual {@link validate} function. If the {@link IValidation.IError} occurs from
322
+ * some parameter, the path would start from `$input.parameters[number]`. Otherwise
323
+ * the path would start from `$input.return`.
324
+ *
325
+ * - `$input.parameters[0].~`
326
+ * - `$input.return.~`
327
+ *
328
+ * By the way, if what you want is not finding every type errors, but just finding
329
+ * the 1st type error, then use {@link assertFunction} instead. Otherwise, what you
330
+ * want is just validating parameters or return value only, you can use
331
+ * {@link validateParameters} or {@link validateReturn} instead.
332
+ *
333
+ * On the other hand, if you don't want to allow any superfluous properties, utilize
334
+ * {@link validateEqualsFunction} or {@link assertEqualsFunction} instead.
335
+ *
336
+ * @template T Target function type
337
+ * @param func Target function to validate
338
+ * @returns The wrapper function with type validations
339
+ *
340
+ * @author Jeongho Nam - https://github.com/samchon
341
+ */
342
+ function validateFunction<T extends (...args: unknown[]) => unknown>(
343
+ func: T,
344
+ ): T extends (...args: infer Arguments) => infer Output
345
+ ? Output extends Promise<infer R>
346
+ ? (...args: Arguments) => Promise<IValidation<R>>
347
+ : (...args: Arguments) => IValidation<Output>
348
+ : never;
349
+
350
+ /**
351
+ * @internal
352
+ */
353
+ function validateFunction(): never {
354
+ halt("validateFunction");
355
+ }
356
+ const validateFunctionPure = /** @__PURE__ */ Object.assign<
357
+ typeof validateFunction,
358
+ {}
359
+ >(validateFunction, /** @__PURE__ */ Namespace.validate());
360
+ export { validateFunctionPure as validateFunction };
361
+
362
+ /**
363
+ * Validates parameters.
364
+ *
365
+ * Validates a function, by wrapping the function and checking its parameters through
366
+ * {@link validate} function. If some parameter does not match the expected type, it
367
+ * returns {@link IValidation.IError} typed object. Otherwise there's no type error,
368
+ * it returns {@link IValidation.ISuccess} typed object instead.
369
+ *
370
+ * For reference, {@link IValidation.IError.path} would be a little bit different with
371
+ * individual {@link validate} function. If the {@link IValidation.IError} occurs from
372
+ * some parameter, the path would start from `$input.parameters[number]`.
373
+ *
374
+ * By the way, if what you want is not finding every type errors, but just finding
375
+ * the 1st type error, then use {@link assertParameters} instead. Otherwise, what you
376
+ * want is not only validating parameters, but also validating return value, you can
377
+ * use {@link validateFunction} instead.
378
+ *
379
+ * On the other hand, if you don't want to allow any superfluous properties, utilize
380
+ * {@link validateEqualsParameters} or {@link assertEqualsParameters} instead.
381
+ *
382
+ * @template T Target function type
383
+ * @param func Target function to validate
384
+ * @returns The wrapper function with type validations
385
+ *
386
+ * @author Jeongho Nam - https://github.com/samchon
387
+ */
388
+ function validateReturn<T extends (...args: unknown[]) => unknown>(
389
+ func: T,
390
+ ): T extends (...args: infer Arguments) => infer Output
391
+ ? Output extends Promise<infer R>
392
+ ? (...args: Arguments) => Promise<IValidation<R>>
393
+ : (...args: Arguments) => IValidation<Output>
394
+ : never;
395
+
396
+ /**
397
+ * @internal
398
+ */
399
+ function validateReturn(): never {
400
+ halt("validateReturn");
401
+ }
402
+ const validateReturnPure = /** @__PURE__ */ Object.assign<
403
+ typeof validateReturn,
404
+ {}
405
+ >(validateReturn, /** @__PURE__ */ Namespace.validate());
406
+ export { validateReturnPure as validateReturn };
407
+
408
+ /**
409
+ * Validates a function with strict equality.
410
+ *
411
+ * Validates a function with strict equality, by wrapping the function and checking
412
+ * its parameters and return value through {@link validateEquals} function. If some
413
+ * parameter or return value does not match the expected type, it returns
414
+ * {@link IValidation.IError} typed object. Otherwise there's no type error, it
415
+ * returns {@link IValidation.ISuccess} typed object instead.
416
+ *
417
+ * For reference, {@link IValidation.IError.path} would be a little bit different with
418
+ * individual {@link validateEquals} function. If the {@link IValidation.IError} occurs
419
+ * from some parameter, the path would start from `$input.parameters[number]`. Otherwise
420
+ * the path would start from `$input.return`.
421
+ *
422
+ * - `$input.parameters[0].~`
423
+ * - `$input.return.~`
424
+ *
425
+ * By the way, if what you want is not finding every type errors, but just finding
426
+ * the 1st type error, then use {@link assertEqualsFunction} instead. Otherwise, what
427
+ * you want is just validating parameters or return value only, you can use
428
+ * {@link validateEqualsParameters} or {@link validateEqualsReturn} instead.
429
+ *
430
+ * On the other hand, if you want to allow any superfluous properties, utilize
431
+ * {@link validateFunction} or {@link assertFunction} instead.
432
+ *
433
+ * @template T Target function type
434
+ * @param func Target function to validate
435
+ * @returns The wrapper function with type validations
436
+ *
437
+ * @author Jeongho Nam - https://github.com/samchon
438
+ */
439
+ function validateEqualsFunction<T extends (...args: unknown[]) => unknown>(
440
+ func: T,
441
+ ): T extends (...args: infer Arguments) => infer Output
442
+ ? Output extends Promise<infer R>
443
+ ? (...args: Arguments) => Promise<IValidation<R>>
444
+ : (...args: Arguments) => IValidation<Output>
445
+ : never;
446
+
447
+ /**
448
+ * @internal
449
+ */
450
+ function validateEqualsFunction(): never {
451
+ halt("validateEqualsFunction");
452
+ }
453
+ const validateEqualsFunctionPure = /** @__PURE__ */ Object.assign<
454
+ typeof validateEqualsFunction,
455
+ {}
456
+ >(validateEqualsFunction, /** @__PURE__ */ Namespace.validate());
457
+ export { validateEqualsFunctionPure as validateEqualsFunction };
458
+
459
+ /**
460
+ * Validates parameters with strict equality.
461
+ *
462
+ * Validates a function, by wrapping the function and checking its parameters through
463
+ * {@link validateEquals} function. If some parameter does not match the expected type,
464
+ * it returns {@link IValidation.IError} typed object. Otherwise there's no type error,
465
+ * it returns {@link IValidation.ISuccess} typed object instead.
466
+ *
467
+ * For reference, {@link IValidation.IError.path} would be a little bit different with
468
+ * individual {@link validateEquals} function. If the {@link IValidation.IError} occurs
469
+ * from some parameter, the path would start from `$input.parameters[number]`.
470
+ *
471
+ * By the way, if what you want is not finding every type errors, but just finding
472
+ * the 1st type error, then use {@link assertEqualsParameters} instead. Otherwise,
473
+ * what you want is not only validating parameters, but also validating return value,
474
+ * you can use {@link validateEqualsFunction} instead.
475
+ *
476
+ * On the other hand, if you want to allow any superfluous properties, utilize
477
+ * {@link validateParameters} or {@link assertParameters} instead.
478
+ *
479
+ * @template T Target function type
480
+ * @param func Target function to validate
481
+ * @returns The wrapper function with type validations
482
+ *
483
+ * @author Jeongho Nam - https://github.com/samchon
484
+ */
485
+ function validateEqualsParameters<T extends (...args: unknown[]) => unknown>(
486
+ func: T,
487
+ ): T extends (...args: infer Arguments) => infer Output
488
+ ? Output extends Promise<infer R>
489
+ ? (...args: Arguments) => Promise<IValidation<R>>
490
+ : (...args: Arguments) => IValidation<Output>
491
+ : never;
492
+
493
+ /**
494
+ * @internal
495
+ */
496
+ function validateEqualsParameters(): never {
497
+ halt("validateEqualsParameters");
498
+ }
499
+ const validateEqualsParametersPure = /** @__PURE__ */ Object.assign<
500
+ typeof validateEqualsParameters,
501
+ {}
502
+ >(validateEqualsParameters, /** @__PURE__ */ Namespace.validate());
503
+ export { validateEqualsParametersPure as validateEqualsParameters };
504
+
505
+ /**
506
+ * Validates return value with strict equality.
507
+ *
508
+ * Validates a function, by wrapping the function and checking its return value through
509
+ * {@link validateEquals} function. If the return value does not match the expected type,
510
+ * it returns {@link IValidation.IError} typed object. Otherwise there's no type error,
511
+ * it returns {@link IValidation.ISuccess} typed object instead.
512
+ *
513
+ * For reference, {@link IValidation.IError.path} would be a little bit different with
514
+ * individual {@link validateEquals} function. If the {@link IValidation.IError} occurs
515
+ * from the return value, the path would start from `$input.return`.
516
+ *
517
+ * By the way, if what you want is not finding every type errors, but just finding
518
+ * the 1st type error, then use {@link assertEqualsReturn} instead. Otherwise, what you
519
+ * want is not only validating return value, but also validating parameters, you can use
520
+ * {@link validateEqualsFunction} instead.
521
+ *
522
+ * On the other hand, if you want to allow any superfluous properties, utilize
523
+ * {@link validateReturn} or {@link assertReturn} instead.
524
+ *
525
+ * @template T Target function type
526
+ * @param func Target function to validate
527
+ * @returns The wrapper function with type validations
528
+ *
529
+ * @author Jeongho Nam - https://github.com/samchon
530
+ */
531
+ function validateEqualsReturn<T extends (...args: unknown[]) => unknown>(
532
+ func: T,
533
+ ): T extends (...args: infer Arguments) => infer Output
534
+ ? Output extends Promise<infer R>
535
+ ? (...args: Arguments) => Promise<IValidation<R>>
536
+ : (...args: Arguments) => IValidation<Output>
537
+ : never;
538
+
539
+ /**
540
+ * @internal
541
+ */
542
+ function validateEqualsReturn(): never {
543
+ halt("validateEqualsReturn");
544
+ }
545
+ const validateEqualsReturnPure = /** @__PURE__ */ Object.assign<
546
+ typeof validateEqualsReturn,
547
+ {}
548
+ >(validateEqualsReturn, /** @__PURE__ */ Namespace.validate());
549
+ export { validateEqualsReturnPure as validateEqualsReturn };
550
+
551
+ /* -----------------------------------------------------------
552
+ HALTER
553
+ ----------------------------------------------------------- */
554
+ /**
555
+ * @internal
556
+ */
557
+ function halt(name: string): never {
558
+ throw new Error(
559
+ `Error on typia.functional.${name}(): no transform has been configured. Read and follow https://typia.io/docs/setup please.`,
560
+ );
561
+ }
package/src/module.ts CHANGED
@@ -6,6 +6,7 @@ import { IValidation } from "./IValidation";
6
6
  import { Resolved } from "./Resolved";
7
7
  import { TypeGuardError } from "./TypeGuardError";
8
8
 
9
+ export * as functional from "./functional";
9
10
  export * as http from "./http";
10
11
  export * as json from "./json";
11
12
  export * as misc from "./misc";
@@ -0,0 +1,44 @@
1
+ import ts from "typescript";
2
+ import { IProject } from "../../transformers/IProject";
3
+ import { FunctionalAssertParametersProgrammer } from "./FunctionalAssertParametersProgrammer";
4
+ import { FunctionAssertReturnProgrammer } from "./FunctionalAssertReturnProgrammer";
5
+
6
+ export namespace FunctionalAssertFunctionProgrammer {
7
+ export const write =
8
+ (project: IProject) =>
9
+ (modulo: ts.LeftHandSideExpression) =>
10
+ (equals: boolean) =>
11
+ (
12
+ expression: ts.Expression,
13
+ declaration: ts.FunctionDeclaration,
14
+ init?: ts.Expression,
15
+ ) => {
16
+ const params = FunctionalAssertParametersProgrammer.prepare(project)(
17
+ modulo,
18
+ )(equals)(declaration, init);
19
+ const output = FunctionAssertReturnProgrammer.prepare(project)(modulo)(
20
+ equals,
21
+ )(expression, declaration, init);
22
+ return ts.factory.createFunctionDeclaration(
23
+ output.async
24
+ ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)]
25
+ : undefined,
26
+ undefined,
27
+ undefined,
28
+ undefined,
29
+ declaration.parameters,
30
+ declaration.type,
31
+ ts.factory.createBlock(
32
+ [
33
+ params.assert,
34
+ output.assert,
35
+ params.call,
36
+ output.variable,
37
+ output.call,
38
+ output.returns,
39
+ ],
40
+ true,
41
+ ),
42
+ );
43
+ };
44
+ }