ts-predicate
Version:
TypeScript predicates and assertions library
282 lines (281 loc) • 8.92 kB
JavaScript
import { TypeGuard } from "./TypeGuard.js";
/**
* TypeAssertion
*
* @class
*/
class TypeAssertion {
/**
* IsDefined
*
* @description Assertion that check if a value is defined.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is undefined, null or NaN
* @return {void} nothing
*/
static IsDefined(value) {
if (!TypeGuard.IsDefined(value)) {
throw new Error("value is undefined, null, or NaN");
}
}
/**
* IsBoolean
*
* @description Assertion that check if a value is a boolean.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a boolean
* @return {void} nothing
*/
static IsBoolean(value) {
if (!TypeGuard.IsBoolean(value)) {
throw new Error("value is not a boolean");
}
}
/**
* IsNumber
*
* @description Assertion that check if a value is a number.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a number
* @return {void} nothing
*/
static IsNumber(value) {
if (!TypeGuard.IsNumber(value)) {
throw new Error("value is not a number");
}
}
/**
* IsInteger
*
* @description Assertion that check if a value is an integer.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not an integer
* @return {void} nothing
*/
static IsInteger(value) {
TypeAssertion.IsNumber(value);
if (!TypeGuard.IsInteger(value)) {
throw new Error("value is not an integer");
}
}
/**
* IsFiniteNumber
*
* @description Assertion that check if a value is a finite number.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a finite number
* @return {void} nothing
*/
static IsFiniteNumber(value) {
TypeAssertion.IsNumber(value);
if (!TypeGuard.IsFiniteNumber(value)) {
throw new Error("value is not a finite number");
}
}
/**
* IsString
*
* @description Assertion that check if a value is a string.
* @public
* @static
* @param {unknown} value the value
* @param {object} [constraints] some additional check
* @param {number} [constraints.minLength] minimal length
* @param {number} [constraints.maxLength] maximum length
* @throws {Error} if the value is not a string
* @return {void} nothing
*/
static IsString(value, constraints) {
if (!TypeGuard.IsString(value)) {
throw new Error("value is not a string");
}
if (constraints === undefined) {
return;
}
if (constraints.minLength !== undefined && value.length < constraints.minLength) {
throw new Error(`value length is shorter than minimum length ${constraints.minLength.toString()}`);
}
if (constraints.maxLength !== undefined && value.length > constraints.maxLength) {
throw new Error(`value length is greater than maximum length ${constraints.maxLength.toString()}`);
}
}
/**
* IsFilledString
*
* @description Assertion that check if a value is non empty string.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a string
* @return {void} nothing
*/
static IsFilledString(value) {
TypeAssertion.IsString(value, {
/**
*
*/
minLength: 1,
});
}
/**
* IsArray
*
* @description Assertion that check if a value is an array.
* @public
* @static
* @param {unknown} value the value
* @param {object} [constraints] some additional check
* @param {number} [constraints.minLength] minimal length
* @param {void} [constraints.itemGuard] another predicate
* @throws {Error} if the value is not an array
* @throws {Error} if the array does not have enough items {@link constraints.minLength}
* @throws {Error} if the array has some item which does not comply the {@link constraints.itemGuard} predicate
* @return {void} nothing
*/
static IsArray(value, constraints) {
if (!TypeGuard.IsArray(value)) {
throw new Error("value is not an array");
}
if (constraints === undefined) {
return;
}
if (constraints.minLength !== undefined && value.length < constraints.minLength) {
throw new Error("value is an array, but it doesn't have enough items");
}
// eslint-disable-next-line unicorn/no-array-callback-reference -- Intended purpose
if (constraints.itemGuard !== undefined && !value.every(constraints.itemGuard)) {
throw new Error("value is an array, but some items are invalid");
}
}
/**
* IsPopulatedArray
*
* @description Assertion that check if a value is an array with at least one item.
* @public
* @static
* @param {unknown} value the value
* @param {object} [constraints] some additional check
* @param {number} [constraints.minLength] minimal length
* @param {void} [constraints.itemGuard] another predicate
* @throws {Error} if the value is not an array
* @throws {Error} if the array does not have enough items {@link constraints.minLength}
* @throws {Error} if the array has some item which does not comply the {@link constraints.itemGuard} predicate
* @return {void} nothing
*/
static IsPopulatedArray(value, constraints) {
TypeAssertion.IsArray(value, {
/**
*
*/
minLength: 1,
...constraints,
});
}
/**
* IsRecord
*
* @description Assertion that check if a value is a record.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a record
* @return {void} nothing
*/
static IsRecord(value) {
if (!TypeGuard.IsRecord(value)) {
throw new Error("value is not a record");
}
}
/**
* IsObject
*
* @description Assertion that check if a value is an object.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not an object
* @return {void} nothing
*/
static IsObject(value) {
if (!TypeGuard.IsObject(value)) {
throw new Error("value is not an object");
}
}
/**
* IsFunction
*
* @description Assertion that check if a value is a function.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not a function
* @return {void} nothing
*/
// eslint-disable-next-line @typescript-eslint/ban-types -- Allow proper function inference
static IsFunction(value) {
if (!TypeGuard.IsFunction(value)) {
throw new Error("value is not a function");
}
}
/**
* IsCallable
*
* @description Assertion that check if a value is callable.
* @public
* @static
* @param {unknown} value the value
* @throws {Error} if the value is not callable
* @return {void} nothing
*/
// eslint-disable-next-line @typescript-eslint/ban-types -- Allow proper function inference
static IsCallable(value) {
if (!TypeGuard.IsCallable(value)) {
throw new Error("value is not a callable");
}
}
/**
* HasNullableProperty
*
* @description Predicate that check if an object as a nullable property.
* @public
* @static
* @param {object} value the object
* @param {string} property the property
* @throws {Error} if the value does not have a property named {@link property}
* @return {void} nothing
*/
static HasNullableProperty(value, property) {
if (!TypeGuard.HasNullableProperty(value, property)) {
throw new Error(`value does not have a property named "${property}"`);
}
}
/**
* HasProperty
*
* @description Predicate that check if an object as a property.
* @public
* @static
* @param {object} value the object
* @param {string} property the property
* @throws {Error} if the value does not have a property named {@link property}
* @throws {Error} if the {@link property} is undefined, null or NaN
* @return {void} nothing
*/
static HasProperty(value, property) {
TypeAssertion.HasNullableProperty(value, property);
if (!TypeGuard.IsDefined(value[property])) {
throw new Error(`value has a property named "${property}", but it is undefined, null, or NaN`);
}
}
}
export { TypeAssertion };