Skip to content

Commit

Permalink
Complete #469 - new function asserGuard().
Browse files Browse the repository at this point in the history
Added new function `typia.assertGuard<T>()` function which performs the assertion guard of TypeScript.
  • Loading branch information
samchon committed Nov 17, 2023
1 parent 81d2298 commit 9820792
Show file tree
Hide file tree
Showing 1,138 changed files with 142,938 additions and 26 deletions.
13 changes: 13 additions & 0 deletions build/internal/TestFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export namespace TestFeature {
creatable: true,
spoilable: true,
},
{
module: null,
method: "assertGuard",
creatable: true,
spoilable: true,
},
{
module: null,
method: "validate",
Expand All @@ -59,6 +65,13 @@ export namespace TestFeature {
spoilable: false,
strict: true,
},
{
module: null,
method: "assertGuardEquals",
creatable: true,
spoilable: false,
strict: true,
},
{
module: null,
method: "validateEquals",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typia",
"version": "5.3.0-dev.20231112",
"version": "5.3.0-dev.20231117",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "5.3.0-dev.20231112",
"version": "5.3.0-dev.20231117",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -72,7 +72,7 @@
},
"homepage": "https://typia.io",
"dependencies": {
"typia": "5.3.0-dev.20231112"
"typia": "5.3.0-dev.20231117"
},
"peerDependencies": {
"typescript": ">=4.8.0 <5.3.0"
Expand Down
1 change: 1 addition & 0 deletions src/AssertionGuard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type AssertionGuard<T> = (input: unknown) => asserts input is T;
252 changes: 252 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Namespace } from "./functional/Namespace";

import { AssertionGuard } from "./AssertionGuard";
import { IRandomGenerator } from "./IRandomGenerator";
import { IValidation } from "./IValidation";
import { Resolved } from "./Resolved";
Expand All @@ -15,6 +16,7 @@ export * as tags from "./tags";
export * from "./schemas/json/IJsonApplication";
export * from "./schemas/json/IJsonComponents";
export * from "./schemas/json/IJsonSchema";
export * from "./AssertionGuard";
export * from "./IRandomGenerator";
export * from "./IValidation";
export * from "./TypeGuardError";
Expand All @@ -38,6 +40,8 @@ export * from "./SnakeCase";
* If what you want is not asserting but just knowing whether the parametric value is
* following the type `T` or not, you can choose the {@link is} function instead.
* Otherwise you want to know all the errors, {@link validate} is the way to go.
* Also, if you want to automatically cast the parametric value to the type `T`
* when no problem (perform the assertion guard of type).
*
* On the other and, if you don't want to allow any superfluous property that is not
* enrolled to the type `T`, you can use {@link assertEquals} function instead.
Expand Down Expand Up @@ -82,6 +86,66 @@ export function assert(): never {
}
Object.assign(assert, Namespace.assert("assert"));

/**
* Assertion guard of a value type.
*
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
* reason, if the parametric value is not following the type `T`. Otherwise, the
* value is following the type `T`, nothing would be returned, but the input value
* would be automatically casted to the type `T`. This is the concept of
* "assertion guard" of a value type.
*
* If what you want is not asserting but just knowing whether the parametric value is
* following the type `T` or not, you can choose the {@link is} function instead.
* Otherwise you want to know all the errors, {@link validate} is the way to go.
* Also, if you want to returns the parametric value when no problem, you can use
* {@link assert} function instead.
*
* On the other and, if you don't want to allow any superfluous property that is not
* enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.
*
* @template T Type of the input value
* @param input A value to be asserted
* @throws A {@link TypeGuardError} instance with detailed reason
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertGuard<T>(input: T): asserts input is T;

/**
* Assertion guard of a value type.
*
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
* reason, if the parametric value is not following the type `T`. Otherwise, the
* value is following the type `T`, nothing would be returned, but the input value
* would be automatically casted to the type `T`. This is the concept of
* "assertion guard" of a value type.
*
* If what you want is not asserting but just knowing whether the parametric value is
* following the type `T` or not, you can choose the {@link is} function instead.
* Otherwise you want to know all the errors, {@link validate} is the way to go.
* Also, if you want to returns the parametric value when no problem, you can use
* {@link assert} function instead.
*
* On the other and, if you don't want to allow any superfluous property that is not
* enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.
*
* @template T Type of the input value
* @param input A value to be asserted
* @throws A {@link TypeGuardError} instance with detailed reason
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertGuard<T>(input: unknown): asserts input is T;

/**
* @internal
*/
export function assertGuard(): never {
halt("assertGuard");
}
Object.assign(assertGuard, Namespace.assert("assertGuard"));

/**
* Tests a value type.
*
Expand Down Expand Up @@ -257,6 +321,72 @@ export function assertEquals(): never {
}
Object.assign(assertEquals, Namespace.assert("assertEquals"));

/**
* Assertion guard of a type with equality.
*
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
* reason, if the parametric value is not following the type `T` or some superfluous
* property that is not listed on the type `T` has been found.
*
* Otherwise, the value is following the type `T` without any superfluous property,
* nothing would be returned, but the input value would be automatically casted to
* the type `T`. This is the concept of "assertion guard" of a value type.
*
* If what you want is not asserting but just knowing whether the parametric value is
* following the type `T` or not, you can choose the {@link equals} function instead.
* Otherwise, you want to know all the errors, {@link validateEquals} is the way to go.
* Also, if you want to returns the parametric value when no problem, you can use
* {@link assert} function instead.
*
* On the other hand, if you want to allow superfluous property that is not enrolled
* to the type `T`, you can use {@link assertEquals} function instead.
*
* @template T Type of the input value
* @param input A value to be asserted
* @returns Parametric input value casted as `T`
* @throws A {@link TypeGuardError} instance with detailed reason
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertGuardEquals<T>(input: T): asserts input is T;

/**
* Assertion guard of a type with equality.
*
* Asserts a parametric value type and throws a {@link TypeGuardError} with detailed
* reason, if the parametric value is not following the type `T` or some superfluous
* property that is not listed on the type `T` has been found.
*
* Otherwise, the value is following the type `T` without any superfluous property,
* nothing would be returned, but the input value would be automatically casted to
* the type `T`. This is the concept of "assertion guard" of a value type.
*
* If what you want is not asserting but just knowing whether the parametric value is
* following the type `T` or not, you can choose the {@link equals} function instead.
* Otherwise, you want to know all the errors, {@link validateEquals} is the way to go.
* Also, if you want to returns the parametric value when no problem, you can use
* {@link assertEquals} function instead.
*
* On the other hand, if you want to allow superfluous property that is not enrolled
* to the type `T`, you can use {@link assertGuard} function instead.
*
* @template T Type of the input value
* @param input A value to be asserted
* @returns Parametric input value casted as `T`
* @throws A {@link TypeGuardError} instance with detailed reason
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertGuardEquals<T>(input: unknown): asserts input is T;

/**
* @internal
*/
export function assertGuardEquals(): never {
halt("assertGuardEquals");
}
Object.assign(assertGuardEquals, Namespace.assert("assertGuardEquals"));

/**
* Tests equality between a value and its type.
*
Expand Down Expand Up @@ -456,6 +586,65 @@ export function createAssert<T>(): (input: unknown) => T {
}
Object.assign(createAssert, assert);

/**
* Creates a reusable {@link assertGuard} function.
*
* Note that, you've to declare the variable type of the factory function caller
* like below. If you don't declare the variable type, compilation error be thrown.
* This is the special rule of the TypeScript compiler.
*
* ```typescript
* // MUST DECLARE THE VARIABLE TYPE
* const func: typia.AssertionGuard<number> = typia.createAssertGuard<number>();
*
* // IF NOT, COMPILATION ERROR BE OCCURED
* const func = typia.createAssertGuard<number>();
* ```
*
* > *Assertions require every name in the call target to be declared with an*
* > *explicit type annotation.*
*
* @danger You must configure the generic argument `T`
* @returns Nothing until you configure the generic argument `T`
* @throws compile error
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssertGuard(): never;

/**
* Creates a reusable {@link assertGuard} function.
*
* Note that, you've to declare the variable type of the factory function caller
* like below. If you don't declare the variable type, compilation error be thrown.
* This is the special rule of the TypeScript compiler.
*
* ```typescript
* // MUST DECLARE THE VARIABLE TYPE
* const func: typia.AssertionGuard<number> = typia.createAssertGuard<number>();
*
* // IF NOT, COMPILATION ERROR BE OCCURED
* const func = typia.createAssertGuard<number>();
* ```
*
* > *Assertions require every name in the call target to be declared with an*
* > *explicit type annotation.*
*
* @returns Nothing until you configure the generic argument `T`
* @throws compile error
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssertGuard<T>(): (input: unknown) => AssertionGuard<T>;

/**
* @internal
*/
export function createAssertGuard<T>(): (input: unknown) => AssertionGuard<T> {
halt("createAssertGuard");
}
Object.assign(createAssertGuard, assertGuard);

/**
* Creates a reusable {@link is} function.
*
Expand Down Expand Up @@ -543,6 +732,69 @@ export function createAssertEquals<T>(): (input: unknown) => T {
}
Object.assign(createAssertEquals, assertEquals);

/**
* Creates a reusable {@link assertGuardEquals} function.
*
* Note that, you've to declare the variable type of the factory function caller
* like below. If you don't declare the variable type, compilation error be thrown.
* This is the special rule of the TypeScript compiler.
*
* ```typescript
* // MUST DECLARE THE VARIABLE TYPE
* const func: typia.AssertionGuard<number> = typia.createAssertGuardEquals<number>();
*
* // IF NOT, COMPILATION ERROR BE OCCURED
* const func = typia.createAssertGuardEquals<number>();
* ```
*
* > *Assertions require every name in the call target to be declared with an*
* > *explicit type annotation.*
*
* @danger You must configure the generic argument `T`
* @returns Nothing until you configure the generic argument `T`
* @throws compile error
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssertGuardEquals(): never;

/**
* Creates a reusable {@link assertGuardEquals} function.
*
* Note that, you've to declare the variable type of the factory function caller
* like below. If you don't declare the variable type, compilation error be thrown.
* This is the special rule of the TypeScript compiler.
*
* ```typescript
* // MUST DECLARE THE VARIABLE TYPE
* const func: typia.AssertionGuard<number> = typia.createAssertGuardEquals<number>();
*
* // IF NOT, COMPILATION ERROR BE OCCURED
* const func = typia.createAssertGuardEquals<number>();
* ```
*
* > *Assertions require every name in the call target to be declared with an*
* > *explicit type annotation.*
*
* @returns Nothing until you configure the generic argument `T`
* @throws compile error
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssertGuardEquals<T>(): (
input: unknown,
) => AssertionGuard<T>;

/**
* @internal
*/
export function createAssertGuardEquals<T>(): (
input: unknown,
) => AssertionGuard<T> {
halt("createAssertGuardEquals");
}
Object.assign(createAssertGuardEquals, assertGuardEquals);

/**
* Creates a reusable {@link equals} function.
*
Expand Down
Loading

0 comments on commit 9820792

Please sign in to comment.