UNPKG

letype

Version:

Type checker for any data structures

233 lines (190 loc) 6.79 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.Letype = {})); }(this, (function (exports) { 'use strict'; var CustomType = function CustomType () {}; var Any = /*@__PURE__*/(function (CustomType) { function Any () { CustomType.apply(this, arguments); } if ( CustomType ) Any.__proto__ = CustomType; Any.prototype = Object.create( CustomType && CustomType.prototype ); Any.prototype.constructor = Any; Any.prototype.parse = function parse () { return true; }; return Any; }(CustomType)); /** * @param {any} value * @param {Function|RegExp|Array|Record<any, any>} type * @param {string[]} path * @param {boolean} silent * @returns {boolean} */ function typeCheck(value, type, path, silent) { if ( path === void 0 ) path = []; if ( silent === void 0 ) silent = true; if (typeof type === 'function' && type.prototype instanceof CustomType) { // @ts-ignore // eslint-disable-next-line new-cap var ref = new type(); var parse = ref.parse; if (typeof parse === 'function') { return parse(value); } } var retype = ((typeof type === 'function') ? type() : type); /** @type {string} */ var typed = typeof retype; var constructorsMatch = value !== undefined && value !== null && value.constructor === type; if (type === Date) { return constructorsMatch; } if (type && type.constructor === RegExp && retype instanceof RegExp) { /** @type {boolean} */ var typeChecked = retype.test(value); if (!typeChecked && !silent) { console.error(("Type error: Expected " + (path.length > 0 ? ("`" + (path.join('.')) + "`") : 'value') + " as `" + value + "` to pass regexp `" + retype + "`")); } return typeChecked; } if (type === RegExp) { return constructorsMatch; } if (constructorsMatch) { return true; } if (typed === 'object' && typeof value === 'object') { var valid = true; // Uncalled Array function if (type && type instanceof Function && type.name === 'Array' && type.constructor instanceof Function) { return (value && value.constructor) === (type && type.constructor); } if (type instanceof Array && type.length === 1) { if (!(value && value.length > -1)) { return false; } // eslint-disable-next-line no-restricted-syntax for (var item in value) { if ({}.hasOwnProperty.call(value, item)) { var typeChecked$1 = typeCheck(value[item], type[0], path.concat(item), silent); if (valid) { valid = typeChecked$1; } } } } else { var newValue = Object.assign({}, type, value); // eslint-disable-next-line no-restricted-syntax for (var item$1 in newValue) { if ({}.hasOwnProperty.call(newValue, item$1)) { var typeChecked$2 = typeCheck(newValue[item$1], type[item$1], path.concat(item$1), silent); if (valid) { valid = typeChecked$2; } } } } return valid; } // eslint-disable-next-line valid-typeof var checked = typeof value === typed; if (!checked) { if (value === undefined) { if (!silent) { console.error(("Type error: " + (path.length > 0 ? ("`" + (path.join('.')) + "`") : 'Value') + " is undefined! Required value of type `" + typed + "`")); } } else if (retype === undefined) { if (!silent) { console.error(("Type error: " + (path.length > 0 ? ("`" + (path.join('.')) + "`") : 'Value') + " is defined as `" + value + "`! But it should not be defined at all!")); } } else if (!silent) { console.error(("Type error: `" + value + "` is not of type `" + typed + "`" + (path.length > 0 ? (" in `" + (path.join('.')) + "`") : ''))); } } return checked; } /** * @param {any} value * @param {any[]} typeList * @returns {boolean} */ function assert(value) { var typeList = [], len = arguments.length - 1; while ( len-- > 0 ) typeList[ len ] = arguments[ len + 1 ]; if (typeList && typeList.length === 1) { if (!typeCheck(value, typeList[0], [], true)) { throw new TypeError('Type checker found some type mismatches!'); } } else if (typeList && typeList.length > 1) { var valid = false; typeList.forEach(function (type) { return !valid && (valid = typeCheck(value, type, [], true)); }); if (!valid) { throw new TypeError(("`" + value + "` is not any of types: " + (typeList.map(function (t) { return ("`" + (t.name) + "`"); }).join(', ')))); } } return true; } /** * @param {any[]} types * @returns {typeof OrType} */ function Or() { var types = [], len = arguments.length; while ( len-- ) types[ len ] = arguments[ len ]; var OrType = /*@__PURE__*/(function (CustomType) { function OrType () { CustomType.apply(this, arguments); } if ( CustomType ) OrType.__proto__ = CustomType; OrType.prototype = Object.create( CustomType && CustomType.prototype ); OrType.prototype.constructor = OrType; OrType.prototype.parse = function parse (value) { return assert.apply(void 0, [ value ].concat( types )); }; return OrType; }(CustomType)); return OrType; } var Undefined = /*@__PURE__*/(function (CustomType) { function Undefined () { CustomType.apply(this, arguments); } if ( CustomType ) Undefined.__proto__ = CustomType; Undefined.prototype = Object.create( CustomType && CustomType.prototype ); Undefined.prototype.constructor = Undefined; Undefined.prototype.parse = function parse (value) { return typeof value === 'undefined'; }; return Undefined; }(CustomType)); var types = { Any: Any, Or: Or, Custom: CustomType, Undefined: Undefined, }; /** * @param {any} value * @param {any[]} typeList * @returns {boolean} */ function check(value) { var typeList = [], len = arguments.length - 1; while ( len-- > 0 ) typeList[ len ] = arguments[ len + 1 ]; try { assert.apply(void 0, [ value ].concat( typeList )); } catch (e) { return false; } return true; } exports.assert = assert; exports.check = check; exports.types = types; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=letype.js.map