Skip to content

Commit 318fe14

Browse files
authored
Merge pull request #872 from samchon/features/assertGuard
Complete #469 - new function `asserGuard()`.
2 parents 81d2298 + c476271 commit 318fe14

File tree

1,144 files changed

+143232
-38
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,144 files changed

+143232
-38
lines changed

build/internal/TestFeature.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ export namespace TestFeature {
3737
creatable: true,
3838
spoilable: true,
3939
},
40+
{
41+
module: null,
42+
method: "assertGuard",
43+
creatable: true,
44+
spoilable: true,
45+
},
4046
{
4147
module: null,
4248
method: "validate",
@@ -59,6 +65,13 @@ export namespace TestFeature {
5965
spoilable: false,
6066
strict: true,
6167
},
68+
{
69+
module: null,
70+
method: "assertGuardEquals",
71+
creatable: true,
72+
spoilable: false,
73+
strict: true,
74+
},
6275
{
6376
module: null,
6477
method: "validateEquals",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typia",
3-
"version": "5.3.0-dev.20231112",
3+
"version": "5.3.0-dev.20231117",
44
"description": "Superfast runtime validators with only one line",
55
"main": "lib/index.js",
66
"typings": "lib/index.d.ts",

packages/typescript-json/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typescript-json",
3-
"version": "5.3.0-dev.20231112",
3+
"version": "5.3.0-dev.20231117",
44
"description": "Superfast runtime validators with only one line",
55
"main": "lib/index.js",
66
"typings": "lib/index.d.ts",
@@ -72,7 +72,7 @@
7272
},
7373
"homepage": "https://typia.io",
7474
"dependencies": {
75-
"typia": "5.3.0-dev.20231112"
75+
"typia": "5.3.0-dev.20231117"
7676
},
7777
"peerDependencies": {
7878
"typescript": ">=4.8.0 <5.3.0"

src/AssertionGuard.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type AssertionGuard<T> = (input: unknown) => asserts input is T;

src/module.ts

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Namespace } from "./functional/Namespace";
22

3+
import { AssertionGuard } from "./AssertionGuard";
34
import { IRandomGenerator } from "./IRandomGenerator";
45
import { IValidation } from "./IValidation";
56
import { Resolved } from "./Resolved";
@@ -15,6 +16,7 @@ export * as tags from "./tags";
1516
export * from "./schemas/json/IJsonApplication";
1617
export * from "./schemas/json/IJsonComponents";
1718
export * from "./schemas/json/IJsonSchema";
19+
export * from "./AssertionGuard";
1820
export * from "./IRandomGenerator";
1921
export * from "./IValidation";
2022
export * from "./TypeGuardError";
@@ -38,6 +40,8 @@ export * from "./SnakeCase";
3840
* If what you want is not asserting but just knowing whether the parametric value is
3941
* following the type `T` or not, you can choose the {@link is} function instead.
4042
* Otherwise you want to know all the errors, {@link validate} is the way to go.
43+
* Also, if you want to automatically cast the parametric value to the type `T`
44+
* when no problem (perform the assertion guard of type).
4145
*
4246
* On the other and, if you don't want to allow any superfluous property that is not
4347
* enrolled to the type `T`, you can use {@link assertEquals} function instead.
@@ -82,6 +86,66 @@ export function assert(): never {
8286
}
8387
Object.assign(assert, Namespace.assert("assert"));
8488

89+
/**
90+
* Assertion guard of a value type.
91+
*
92+
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
93+
* reason, if the parametric value is not following the type `T`. Otherwise, the
94+
* value is following the type `T`, nothing would be returned, but the input value
95+
* would be automatically casted to the type `T`. This is the concept of
96+
* "Assertion Guard" of a value type.
97+
*
98+
* If what you want is not asserting but just knowing whether the parametric value is
99+
* following the type `T` or not, you can choose the {@link is} function instead.
100+
* Otherwise you want to know all the errors, {@link validate} is the way to go.
101+
* Also, if you want to returns the parametric value when no problem, you can use
102+
* {@link assert} function instead.
103+
*
104+
* On the other and, if you don't want to allow any superfluous property that is not
105+
* enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.
106+
*
107+
* @template T Type of the input value
108+
* @param input A value to be asserted
109+
* @throws A {@link TypeGuardError} instance with detailed reason
110+
*
111+
* @author Jeongho Nam - https://github.com/samchon
112+
*/
113+
export function assertGuard<T>(input: T): asserts input is T;
114+
115+
/**
116+
* Assertion guard of a value type.
117+
*
118+
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
119+
* reason, if the parametric value is not following the type `T`. Otherwise, the
120+
* value is following the type `T`, nothing would be returned, but the input value
121+
* would be automatically casted to the type `T`. This is the concept of
122+
* "Assertion Guard" of a value type.
123+
*
124+
* If what you want is not asserting but just knowing whether the parametric value is
125+
* following the type `T` or not, you can choose the {@link is} function instead.
126+
* Otherwise you want to know all the errors, {@link validate} is the way to go.
127+
* Also, if you want to returns the parametric value when no problem, you can use
128+
* {@link assert} function instead.
129+
*
130+
* On the other and, if you don't want to allow any superfluous property that is not
131+
* enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.
132+
*
133+
* @template T Type of the input value
134+
* @param input A value to be asserted
135+
* @throws A {@link TypeGuardError} instance with detailed reason
136+
*
137+
* @author Jeongho Nam - https://github.com/samchon
138+
*/
139+
export function assertGuard<T>(input: unknown): asserts input is T;
140+
141+
/**
142+
* @internal
143+
*/
144+
export function assertGuard(): never {
145+
halt("assertGuard");
146+
}
147+
Object.assign(assertGuard, Namespace.assert("assertGuard"));
148+
85149
/**
86150
* Tests a value type.
87151
*
@@ -257,6 +321,72 @@ export function assertEquals(): never {
257321
}
258322
Object.assign(assertEquals, Namespace.assert("assertEquals"));
259323

324+
/**
325+
* Assertion guard of a type with equality.
326+
*
327+
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
328+
* reason, if the parametric value is not following the type `T` or some superfluous
329+
* property that is not listed on the type `T` has been found.
330+
*
331+
* Otherwise, the value is following the type `T` without any superfluous property,
332+
* nothing would be returned, but the input value would be automatically casted to
333+
* the type `T`. This is the concept of "Assertion Guard" of a value type.
334+
*
335+
* If what you want is not asserting but just knowing whether the parametric value is
336+
* following the type `T` or not, you can choose the {@link equals} function instead.
337+
* Otherwise, you want to know all the errors, {@link validateEquals} is the way to go.
338+
* Also, if you want to returns the parametric value when no problem, you can use
339+
* {@link assert} function instead.
340+
*
341+
* On the other hand, if you want to allow superfluous property that is not enrolled
342+
* to the type `T`, you can use {@link assertEquals} function instead.
343+
*
344+
* @template T Type of the input value
345+
* @param input A value to be asserted
346+
* @returns Parametric input value casted as `T`
347+
* @throws A {@link TypeGuardError} instance with detailed reason
348+
*
349+
* @author Jeongho Nam - https://github.com/samchon
350+
*/
351+
export function assertGuardEquals<T>(input: T): asserts input is T;
352+
353+
/**
354+
* Assertion guard of a type with equality.
355+
*
356+
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
357+
* reason, if the parametric value is not following the type `T` or some superfluous
358+
* property that is not listed on the type `T` has been found.
359+
*
360+
* Otherwise, the value is following the type `T` without any superfluous property,
361+
* nothing would be returned, but the input value would be automatically casted to
362+
* the type `T`. This is the concept of "Assertion Guard" of a value type.
363+
*
364+
* If what you want is not asserting but just knowing whether the parametric value is
365+
* following the type `T` or not, you can choose the {@link equals} function instead.
366+
* Otherwise, you want to know all the errors, {@link validateEquals} is the way to go.
367+
* Also, if you want to returns the parametric value when no problem, you can use
368+
* {@link assertEquals} function instead.
369+
*
370+
* On the other hand, if you want to allow superfluous property that is not enrolled
371+
* to the type `T`, you can use {@link assertGuard} function instead.
372+
*
373+
* @template T Type of the input value
374+
* @param input A value to be asserted
375+
* @returns Parametric input value casted as `T`
376+
* @throws A {@link TypeGuardError} instance with detailed reason
377+
*
378+
* @author Jeongho Nam - https://github.com/samchon
379+
*/
380+
export function assertGuardEquals<T>(input: unknown): asserts input is T;
381+
382+
/**
383+
* @internal
384+
*/
385+
export function assertGuardEquals(): never {
386+
halt("assertGuardEquals");
387+
}
388+
Object.assign(assertGuardEquals, Namespace.assert("assertGuardEquals"));
389+
260390
/**
261391
* Tests equality between a value and its type.
262392
*
@@ -456,6 +586,65 @@ export function createAssert<T>(): (input: unknown) => T {
456586
}
457587
Object.assign(createAssert, assert);
458588

589+
/**
590+
* Creates a reusable {@link assertGuard} function.
591+
*
592+
* Note that, you've to declare the variable type of the factory function caller
593+
* like below. If you don't declare the variable type, compilation error be thrown.
594+
* This is the special rule of the TypeScript compiler.
595+
*
596+
* ```typescript
597+
* // MUST DECLARE THE VARIABLE TYPE
598+
* const func: typia.AssertionGuard<number> = typia.createAssertGuard<number>();
599+
*
600+
* // IF NOT, COMPILATION ERROR BE OCCURED
601+
* const func = typia.createAssertGuard<number>();
602+
* ```
603+
*
604+
* > *Assertions require every name in the call target to be declared with an*
605+
* > *explicit type annotation.*
606+
*
607+
* @danger You must configure the generic argument `T`
608+
* @returns Nothing until you configure the generic argument `T`
609+
* @throws compile error
610+
*
611+
* @author Jeongho Nam - https://github.com/samchon
612+
*/
613+
export function createAssertGuard(): never;
614+
615+
/**
616+
* Creates a reusable {@link assertGuard} function.
617+
*
618+
* Note that, you've to declare the variable type of the factory function caller
619+
* like below. If you don't declare the variable type, compilation error be thrown.
620+
* This is the special rule of the TypeScript compiler.
621+
*
622+
* ```typescript
623+
* // MUST DECLARE THE VARIABLE TYPE
624+
* const func: typia.AssertionGuard<number> = typia.createAssertGuard<number>();
625+
*
626+
* // IF NOT, COMPILATION ERROR BE OCCURED
627+
* const func = typia.createAssertGuard<number>();
628+
* ```
629+
*
630+
* > *Assertions require every name in the call target to be declared with an*
631+
* > *explicit type annotation.*
632+
*
633+
* @returns Nothing until you configure the generic argument `T`
634+
* @throws compile error
635+
*
636+
* @author Jeongho Nam - https://github.com/samchon
637+
*/
638+
export function createAssertGuard<T>(): (input: unknown) => AssertionGuard<T>;
639+
640+
/**
641+
* @internal
642+
*/
643+
export function createAssertGuard<T>(): (input: unknown) => AssertionGuard<T> {
644+
halt("createAssertGuard");
645+
}
646+
Object.assign(createAssertGuard, assertGuard);
647+
459648
/**
460649
* Creates a reusable {@link is} function.
461650
*
@@ -543,6 +732,69 @@ export function createAssertEquals<T>(): (input: unknown) => T {
543732
}
544733
Object.assign(createAssertEquals, assertEquals);
545734

735+
/**
736+
* Creates a reusable {@link assertGuardEquals} function.
737+
*
738+
* Note that, you've to declare the variable type of the factory function caller
739+
* like below. If you don't declare the variable type, compilation error be thrown.
740+
* This is the special rule of the TypeScript compiler.
741+
*
742+
* ```typescript
743+
* // MUST DECLARE THE VARIABLE TYPE
744+
* const func: typia.AssertionGuard<number> = typia.createAssertGuardEquals<number>();
745+
*
746+
* // IF NOT, COMPILATION ERROR BE OCCURED
747+
* const func = typia.createAssertGuardEquals<number>();
748+
* ```
749+
*
750+
* > *Assertions require every name in the call target to be declared with an*
751+
* > *explicit type annotation.*
752+
*
753+
* @danger You must configure the generic argument `T`
754+
* @returns Nothing until you configure the generic argument `T`
755+
* @throws compile error
756+
*
757+
* @author Jeongho Nam - https://github.com/samchon
758+
*/
759+
export function createAssertGuardEquals(): never;
760+
761+
/**
762+
* Creates a reusable {@link assertGuardEquals} function.
763+
*
764+
* Note that, you've to declare the variable type of the factory function caller
765+
* like below. If you don't declare the variable type, compilation error be thrown.
766+
* This is the special rule of the TypeScript compiler.
767+
*
768+
* ```typescript
769+
* // MUST DECLARE THE VARIABLE TYPE
770+
* const func: typia.AssertionGuard<number> = typia.createAssertGuardEquals<number>();
771+
*
772+
* // IF NOT, COMPILATION ERROR BE OCCURED
773+
* const func = typia.createAssertGuardEquals<number>();
774+
* ```
775+
*
776+
* > *Assertions require every name in the call target to be declared with an*
777+
* > *explicit type annotation.*
778+
*
779+
* @returns Nothing until you configure the generic argument `T`
780+
* @throws compile error
781+
*
782+
* @author Jeongho Nam - https://github.com/samchon
783+
*/
784+
export function createAssertGuardEquals<T>(): (
785+
input: unknown,
786+
) => AssertionGuard<T>;
787+
788+
/**
789+
* @internal
790+
*/
791+
export function createAssertGuardEquals<T>(): (
792+
input: unknown,
793+
) => AssertionGuard<T> {
794+
halt("createAssertGuardEquals");
795+
}
796+
Object.assign(createAssertGuardEquals, assertGuardEquals);
797+
546798
/**
547799
* Creates a reusable {@link equals} function.
548800
*

0 commit comments

Comments
 (0)