typia
Version:
Superfast runtime validators with only one line
706 lines (668 loc) • 29 kB
text/typescript
import { NoTransformConfigurationError } from "./transformers/NoTransformConfigurationError";
import { IValidation } from "./IValidation";
import { TypeGuardError } from "./TypeGuardError";
/* ===========================================================
FUNCTIONAL
- ASSERT
- IS
- VALIDATE
==============================================================
ASSERT
----------------------------------------------------------- */
/**
* Asserts a function.
*
* Asserts a function, by wrapping the function and checking its parameters and
* return value through {@link assert} function. If some parameter or return
* value does not match the expected type, it throws an {@link TypeGuardError} or
* a custom error generated by the _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assert} function. If the {@link TypeGuardError} occurs
* from some parameter, the path would start from `$input.parameters[number]`.
* Otherwise the path would start from `$input.return`.
*
* - `$input.parameters[0].~`
* - `$input.return.~`
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use
* {@link validateFunction} instead. Otherwise, what you want is just asserting
* parameters or return value only, you can use {@link assertParameters} or
* {@link assertReturn} instead.
*
* On the other hand, if don't want to allow any superfluous properties, utilize
* {@link assertEqualsFunction} or {@link validateEqualsFunction} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertFunction<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertFunction(): never {
NoTransformConfigurationError("functional.assertFunction");
}
/**
* Asserts parameters.
*
* Asserts a function, by wrapping the function and checking its parameters
* through {@link assert} function. If some parameter does not match the expected
* type, it throws an {@link TypeGuardError} or a custom error generated by the
* _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assert} function. If the {@link TypeGuardError} occurs
* from some parameter, the path would start from `$input.parameters[number]`.
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use
* {@link validateParameters} instead. Otherwise, what you want is not only
* asserting parameters, but also asserting return value, you can use
* {@link assertFunction} instead.
*
* On the other hand, if don't want to allow any superfluous properties, utilize
* {@link assertEqualsParameters} or {@link validateEqualsParameters} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertParameters<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertParameters(): never {
NoTransformConfigurationError("functional.assertParameters");
}
/**
* Asserts return value.
*
* Asserts a function, by wrapping the function and checking its return value
* through {@link assert} function. If the return value does not match the
* expected type, it throws an {@link TypeGuardError} or a custom error generated
* by the _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assert} function. If the {@link TypeGuardError} occurs
* from the return value, the path would start from `$input.return`.
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use {@link validateReturn}
* instead. Otherwise, what you want is not only asserting return value, but
* also asserting parameters, you can use {@link assertFunction} instead.
*
* On the other hand, if don't want to allow any superfluous properties, utilize
* {@link assertEqualsReturn} or {@link validateEqualsReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertReturn<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertReturn(): never {
NoTransformConfigurationError("functional.assertReturn");
}
/**
* Asserts a function with strict equality.
*
* Asserts a function with strict equality, by wrapping the function and
* checking its parameters and return value through {@link assertEquals}
* function. If some parameter or return value does not match the expected type,
* it throws an {@link TypeGuardError} or a custom error generated by the
* _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assertEquals} function. If the {@link TypeGuardError}
* occurs from some parameter, the path would start from
* `$input.parameters[number]`. Otherwise the path would start from
* `$input.return`.
*
* - `$input.parameters[0].~`
* - `$input.return.~`
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use
* {@link validateEqualsFunction} instead. Otherwise, what you want is just
* asserting parameters or return value only, you can use
* {@link assertEqualsParameters} or {@link assertEqualsReturn} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link assertFunction} or {@link validateFunction} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertEqualsFunction<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertEqualsFunction(): never {
NoTransformConfigurationError("functional.assertEqualsFunction");
}
/**
* Asserts parameters with strict equality.
*
* Asserts a function, by wrapping the function and checking its parameters
* through {@link assertEquals} function. If some parameter does not match the
* expected type, it throws an {@link TypeGuardError} or a custom error generated
* by the _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assertEquals} function. If the {@link TypeGuardError}
* occurs from some parameter, the path would start from
* `$input.parameters[number]`.
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use
* {@link validateEqualsParameters} instead. Otherwise, what you want is not only
* asserting parameters, but also asserting return value, you can use
* {@link assertEqualsFunction} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link assertParameters} or {@link validateParameters} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertEqualsParameters<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertEqualsParameters(): never {
NoTransformConfigurationError("functional.assertEqualsParameters");
}
/**
* Asserts return value with strict equality.
*
* Asserts a function, by wrapping the function and checking its return value
* through {@link assertEquals} function. If the return value does not match the
* expected type, it throws an {@link TypeGuardError} or a custom error generated
* by the _errorFactory_ parameter.
*
* For reference, {@link TypeGuardError.path} would be a little bit different
* with individual {@link assertEquals} function. If the {@link TypeGuardError}
* occurs from the return value, the path would start from `$input.return`.
*
* By the way, if what you want is not just finding the 1st type error through
* assertion, but also finding every type errors, then use
* {@link validateEqualsReturn} instead. Otherwise, what you want is not only
* asserting return value, but also asserting parameters, you can use
* {@link assertEqualsFunction} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link assertReturn} or {@link validateReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to assert
* @param errorFactory Custom error factory. Default is `TypeGuardError`
* @returns The wrapper function with type assertions
* @throws A {@link TypeGuardError} or a custom error generated by _errorFactory_
*/
export function assertEqualsReturn<T extends (...args: any[]) => any>(
func: T,
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): T;
/** @internal */
export function assertEqualsReturn(): never {
NoTransformConfigurationError("functional.assertEqualsReturn");
}
/* -----------------------------------------------------------
IS
----------------------------------------------------------- */
/**
* Tests a function.
*
* Tests a function, by wrapping the function and checking its parameters and
* return value through {@link is} function. If some parameter or return value
* does not match the expected type, it returns `null`. Otherwise there's no
* type error, it returns the result of the function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertFunction} or
* {@link validateFunction} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link equalsFunction}, {@link assertEqualsFunction} or
* {@link validateEqualsFunction} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function isFunction<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function isFunction(): never {
NoTransformConfigurationError("functional.isFunction");
}
/**
* Tests parameters.
*
* Tests a function, by wrapping the function and checking its parameters
* through {@link is} function. If some parameter does not match the expected
* type, it returns `null`. Otherwise there's no type error, it returns the
* result of the function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertParameters} or
* {@link validateParameters} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link equalsParameters}, {@link assertEqualsParameters} or
* {@link validateEqualsParameters} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function isParameters<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function isParameters(): never {
NoTransformConfigurationError("functional.isParameters");
}
/**
* Tests return value.
*
* Tests a function, by wrapping the function and checking its return value
* through {@link is} function. If the return value does not match the expected
* type, it returns `null`. Otherwise there's no type error, it returns the
* result of the function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertReturn} or
* {@link validateReturn} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link equalsReturn}, {@link assertEqualsReturn} or
* {@link validateEqualsReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function isReturn<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function isReturn(): never {
NoTransformConfigurationError("functional.isReturn");
}
/**
* Tests a function with strict equality.
*
* Tests a function with strict equality, by wrapping the function and checking
* its parameters and return value through {@link isEquals} function. If some
* parameter or return value does not match the expected type, it returns
* `null`. Otherwise there's no type error, it returns the result of the
* function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertEqualsFunction} or
* {@link validateEqualsFunction} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link isFunction}, {@link assertFunction} or {@link validateFunction} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function equalsFunction<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function equalsFunction(): never {
NoTransformConfigurationError("functional.equalsFunction");
}
/**
* Tests parameters with strict equality.
*
* Tests a function, by wrapping the function and checking its parameters
* through {@link isEquals} function. If some parameter does not match the
* expected type, it returns `null`. Otherwise there's no type error, it returns
* the result of the function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertEqualsParameters} or
* {@link validateEqualsParameters} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function equalsParameters<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function equalsParameters(): never {
NoTransformConfigurationError("functional.equalsParameters");
}
/**
* Tests return value with strict equality.
*
* Tests a function, by wrapping the function and checking its return value
* through {@link isEquals} function. If the return value does not match the
* expected type, it returns `null`. Otherwise there's no type error, it returns
* the result of the function.
*
* By the way, if you want is not just testing type checking, but also finding
* detailed type error reason(s), then use {@link assertEqualsReturn} or
* {@link validateEqualsReturn} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link isReturn}, {@link assertReturn} or {@link validateReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to test
* @returns The wrapper function with type tests
*/
export function equalsReturn<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<R | null>
: (...args: Arguments) => Output | null
: never;
/** @internal */
export function equalsReturn(): never {
NoTransformConfigurationError("functional.equalsReturn");
}
/* -----------------------------------------------------------
VALIDATE
----------------------------------------------------------- */
/**
* Validates a function.
*
* Validates a function, by wrapping the function and checking its parameters
* and return value through {@link validate} function. If some parameter or
* return value does not match the expected type, it returns
* {@link IValidation.IError} typed object. Otherwise there's no type error, it
* returns {@link IValidation.ISuccess} typed object instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validate} function. If the {@link IValidation.IError}
* occurs from some parameter, the path would start from
* `$input.parameters[number]`. Otherwise the path would start from
* `$input.return`.
*
* - `$input.parameters[0].~`
* - `$input.return.~`
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertFunction} instead.
* Otherwise, what you want is just validating parameters or return value only,
* you can use {@link validateParameters} or {@link validateReturn} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link validateEqualsFunction} or {@link assertEqualsFunction}
* instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateFunction<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateFunction(): never {
NoTransformConfigurationError("functional.validateFunction");
}
/**
* Validates parameters.
*
* Validates a function, by wrapping the function and checking its parameters
* through {@link validate} function. If some parameter does not match the
* expected type, it returns {@link IValidation.IError} typed object. Otherwise
* there's no type error, it returns {@link IValidation.ISuccess} typed object
* instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validate} function. If the {@link IValidation.IError}
* occurs from some parameter, the path would start from
* `$input.parameters[number]`.
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertParameters} instead.
* Otherwise, what you want is not only validating parameters, but also
* validating return value, you can use {@link validateFunction} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link validateEqualsParameters} or {@link assertEqualsParameters}
* instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateParameters<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateParameters(): never {
NoTransformConfigurationError("functional.validateParameters");
}
/**
* Validates return value.
*
* Validates a function, by wrapping the function and checking its return value
* through {@link validate} function. If the return value does not match the
* expected type, it returns {@link IValidation.IError} typed object. Otherwise
* there's no type error, it returns {@link IValidation.ISuccess} typed object
* instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validate} function. If the {@link IValidation.IError}
* occurs from the return value, the path would start from `$input.return`.
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertReturn} instead. Otherwise,
* what you want is not only validating return value, but also validating
* parameters, you can use {@link validateFunction} instead.
*
* On the other hand, if you don't want to allow any superfluous properties,
* utilize {@link validateEqualsReturn} or {@link assertEqualsReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateReturn<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateReturn(): never {
NoTransformConfigurationError("functional.validateReturn");
}
/**
* Validates a function with strict equality.
*
* Validates a function with strict equality, by wrapping the function and
* checking its parameters and return value through {@link validateEquals}
* function. If some parameter or return value does not match the expected type,
* it returns {@link IValidation.IError} typed object. Otherwise there's no type
* error, it returns {@link IValidation.ISuccess} typed object instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validateEquals} function. If the
* {@link IValidation.IError} occurs from some parameter, the path would start
* from `$input.parameters[number]`. Otherwise the path would start from
* `$input.return`.
*
* - `$input.parameters[0].~`
* - `$input.return.~`
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertEqualsFunction} instead.
* Otherwise, what you want is just validating parameters or return value only,
* you can use {@link validateEqualsParameters} or {@link validateEqualsReturn}
* instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link validateFunction} or {@link assertFunction} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateEqualsFunction<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateEqualsFunction(): never {
NoTransformConfigurationError("functional.validateEqualsFunction");
}
/**
* Validates parameters with strict equality.
*
* Validates a function, by wrapping the function and checking its parameters
* through {@link validateEquals} function. If some parameter does not match the
* expected type, it returns {@link IValidation.IError} typed object. Otherwise
* there's no type error, it returns {@link IValidation.ISuccess} typed object
* instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validateEquals} function. If the
* {@link IValidation.IError} occurs from some parameter, the path would start
* from `$input.parameters[number]`.
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertEqualsParameters} instead.
* Otherwise, what you want is not only validating parameters, but also
* validating return value, you can use {@link validateEqualsFunction} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link validateParameters} or {@link assertParameters} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateEqualsParameters<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateEqualsParameters(): never {
NoTransformConfigurationError("functional.validateEqualsParameters");
}
/**
* Validates return value with strict equality.
*
* Validates a function, by wrapping the function and checking its return value
* through {@link validateEquals} function. If the return value does not match
* the expected type, it returns {@link IValidation.IError} typed object.
* Otherwise there's no type error, it returns {@link IValidation.ISuccess} typed
* object instead.
*
* For reference, {@link IValidation.IError.path} would be a little bit different
* with individual {@link validateEquals} function. If the
* {@link IValidation.IError} occurs from the return value, the path would start
* from `$input.return`.
*
* By the way, if what you want is not finding every type errors, but just
* finding the 1st type error, then use {@link assertEqualsReturn} instead.
* Otherwise, what you want is not only validating return value, but also
* validating parameters, you can use {@link validateEqualsFunction} instead.
*
* On the other hand, if you want to allow any superfluous properties, utilize
* {@link validateReturn} or {@link assertReturn} instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template T Target function type
* @param func Target function to validate
* @returns The wrapper function with type validations
*/
export function validateEqualsReturn<T extends (...args: any[]) => any>(
func: T,
): T extends (...args: infer Arguments) => infer Output
? Output extends Promise<infer R>
? (...args: Arguments) => Promise<IValidation<R>>
: (...args: Arguments) => IValidation<Output>
: never;
/** @internal */
export function validateEqualsReturn(): never {
NoTransformConfigurationError("functional.validateEqualsReturn");
}