/** * This module provides native variable type checking utilities. * It has no external dependencies. * No parsing or coercion is performed. * * @module TypeUtils */ const validateUUID = require ( 'uuid-validate' ); // The module definition const TypeUtils = { /** * Is the value a string? * @return {boolean} * @param value Any arbitrary value */ isString: value => typeof value === 'string', /** * Is the value a number? * @return {boolean} * @param value Any arbitrary value */ isNumber: value => { // BigInt's are not interchangeable with Math.Number if ( typeof value === 'bigint' ) { return false; } return !isNaN ( value ) && typeof value === 'number'; }, /** * Is the value an integer? * @return {boolean} * @param value Any arbitrary value */ isInteger: value => { return !TypeUtils.isInfinite ( value ) && TypeUtils.isNumber ( value ) && parseInt ( value, 10 ) === value ; }, /** * Is the value a floating point number? * @return {boolean} * @param value Any arbitrary value */ isFloat: value => { return ( '' + value ).includes ( '.' ) && parseFloat ( value ) === value && !TypeUtils.isInfinite ( value ) ; }, /** * Is the value equal to JavaScript's Infinity? * @return {boolean} * @param value Any arbitrary value */ isInfinite: value => value === Infinity, /** * Is the value a boolean? * @return {boolean} * @param value Any arbitrary value */ isBoolean: value => [ false, true ].includes ( value ), /** * Is the value an object? * @return {boolean} * @param value Any arbitrary value */ isObject: value => { return typeof value === 'object' && !TypeUtils.isArrayLike ( value ) && !TypeUtils.isNull ( value ) ; }, /** * Is the value an array? * @return {boolean} * @param value Any arbitrary value */ isArray: value => Array.isArray ( value ), /** * Is the value array-like (Array, Set or Map)? * @return {boolean} * @param value Any arbitrary value */ isArrayLike: value => value instanceof Set || value instanceof Map || Array.isArray ( value ), /** * Is the value a function? * @return {boolean} * @param value Any arbitrary value */ isFunction: value => typeof value === 'function', /** * Is the value equal to NULL? * @return {boolean} * @param value Any arbitrary value */ isNull: value => value === null, /** * Is the value equal to UNDEFINED? * @return {boolean} * @param value Any arbitrary value */ isUndefined: value => value === undefined, /** * Is the value either NULL or UNDEFINED * @return {boolean} * @param value Any arbitrary value */ isNullOrUndefined: value => [ null, undefined ].includes ( value ), /** * Is the value considered empty? * (Numbers, Booleans aren't ever considered "empty") * @return {boolean} * @param value Any arbitrary value */ isEmpty: value => { // Null / Undefined if ( TypeUtils.isNull ( value ) || TypeUtils.isUndefined ( value ) ) { return true; } // String if ( TypeUtils.isString ( value ) && value.length === 0 ) { return true; } // Arrays if ( TypeUtils.isArray ( value ) ) { return value.length === 0; } // Sets, Maps if ( TypeUtils.isArrayLike ( value ) ) { return value.size === 0; } // Objects if ( TypeUtils.isObject ( value ) && Object.keys ( value ).length === 0 ) { return true; } return false; }, /** * Is the value a Date? * @return {boolean} * @param value Any arbitrary value */ isDate: value => { return ( !TypeUtils.isNullOrUndefined ( value ) && value.constructor === Date && TypeUtils.isInteger ( value.getTime () ) ); }, /** * Is the value a Promise? * @return {boolean} * @param value Any arbitrary value */ isPromise: value => Boolean ( value && TypeUtils.isFunction ( value.then ) ), /** * Is the value a valid specific UUID version? * @return {boolean} * @param value * @param version */ isUUID: ( value, version = 4 ) => validateUUID ( value, version ), /** * Safe wrapper for checking if an object has a property * @return {boolean} * @param value * @param property */ hasProperty: ( value, property ) => { if ( !TypeUtils.isObject ( value ) ) { return false; } return Object.prototype.hasOwnProperty.call ( value, property ); } };