xtype(-2.5) === '{negative_float}'; //#:4:8 Value is number, negative and float xtype(' ') === '{whitespace}'; //#:4:8 Value is string and blank xtype({}) === '{empty_object}'; //#:4:8 Value is object and is empty xtype(['hi']) === '{single_elem_array}'; //#:4:8 Value is array, has exactly one element xtype.type(null) === '{null}'; xtype.type(undefined) === '{undefined}'; xtype.type(NaN) === '{nan}'; xtype.type([]) === '{array}'; xtype.type({}) === '{object}'; xtype.type(new Date()) === '{date}'; xtype.type(function() {}) === '{function}'; xtype.type(/ab+c/i) === '{regexp}'; xtype.type(new Error('No!') === '{error}'; xtype.type(Symbol()) === '{symbol}'; xtype.type('Hi') === '{string}'; xtype.type(new String('Hi')) === '{string}'; xtype.type(25) === '{number}'; xtype.type(new Number(25)) === '{number}'; xtype.type(true) === '{boolean}'; xtype.type(new Boolean(true)) === '{boolean}'; function getArgumentsObject() { return arguments; } xtype.type(getArgumentsObject()) === '{object}'; // However: xtype.typeOf(getArgumentsObject()) === 'arguments'; var customNameScheme = { positive_number: 'pos_num', empty_object: 'emp_obj', blank_string: 'bl_str' /* More entries */ }; xtype.ext.registerNameScheme('my_custom_scheme', customNameScheme); // The custom scheme is now internally registered // and can now be referenced by name: xtype.options.setNameScheme('my_custom_scheme'); xtype({}) === 'emp_obj'; xtype(25) === 'pos_num'; xtype(' ') === 'bl_str'; xtype.is({}, 'emp_obj') === true; xtype.is(25, 'pos_num') === true; xtype.is(' ', 'bl_str') === true; // Switch to the 'compact' name scheme: xtype.options.setNameScheme('compact'); xtype({}) === 'obj0'; // 'obj0' is empty_object in new scheme xtype(25) === 'int+'; // 'int+' is positive_integer in new scheme xtype.is({}, 'obj0') === true; xtype.is(25, 'int+') === true; // Any custom scheme which was already // previously registered can also be used: xtype.options.setNameScheme('my_custom_scheme'); // Switch to the 'compact' name scheme: xtype.options.set({ delimiterPattern: '', nameScheme: 'compact' }); // Or, if using a custom unnamed scheme: xtype.options.set({ delimiterPattern: '', nameScheme: { string: 'str', empty_string: 'emp_str', /* More name scheme entries */ } }); xtype.options.setDelimiterPattern('/'); xtype.is(0, '{zero} / {positive_number}') === true; xtype.is(25, '{zero} / {positive_number}') === true; xtype.is(-3, '{zero} / {positive_number}') === false; // Using a different pattern to also allow the comma character: xtype.options.setDelimiterPattern('[/,]'); xtype.is(25, '{zero}, {positive_number} / {float}') === true; var otherName = xtype.noConflict(); otherName.isPositiveInteger(5) === 'true'; // otherName is now xtypejs // Obtain original xtypejs instance. Here we use nodejs-style // require, but could be any other way of obtaining the module: var xtype = require('xtypejs'); // Because the 'default' name scheme is the default for new xtypejs // module instances, the following statement is not necessary for // a newly created instance, but is included here for clarity: xtype.options.setNameScheme('default'); // Create a new instance (named xtypeCompact in this case) // of xtypejs and set it to use the 'compact' name scheme: var compactNameScheme = require('xtypejs-name-scheme-compact'); var xtypeCompact = xtype.newInstance(); xtypeCompact.ext.registerNameScheme('compact', compactNameScheme); xtypeCompact.options.setNameScheme('compact'); // Now the original instance (xtype) uses the default descriptive type // names of the 'default' scheme, whereas the xtypeCompact instance // uses the concise names of the 'compact' name scheme: xtype(29.3) === 'positive_float'; xtypeCompact(29.3) === '{positive_float}'; // Each can be further configured and used independently of each other. switch (xtype.which(value, ['{multi_char_string}', '{positive_integer}', Product])) { case '{multi_char_string}': // Fetch and display product with value as the product name string case '{positive_integer}': // Fetch and display product with value as the product Id number case Product: // value is already a Product object, so just display it default: // Handle invalid value.. cannot display product } xtype.is(value, '{single_elem_array}, {positive_integer}'); xtype.is(value, xtype.SINGLE_ELEM_ARRAY & xtype.POSITIVE_INTEGER); // The following example returns true if the value is a multi-character // string, a positive integer or a Product instance: xtype.is(value, ['{multi_char_string}', '{positive_integer}', Product]); xtype.not.isNull(null) === false; xtype.not.isFalse(true) === true; xtype.not.isNaN(12) === true; xtype.not.isNegativeNumber(1.3) === true; xtype.not.isWhitespace(' ') === false; xtype.not.isZero(0.0) === false; xtype.not.isEmptyArray(['hi']) === true; xtype.not.isSinglePropObject({ one: 1 }) === false; xtype.not.isMultiPropObject({ one: 1 }) === true; xtype.none.isNan(7, 2.5, NaN, 0, -5) === false; xtype.none.isBlankString('Tom', 0, true, null, ' ') === false; xtype.none.isFloat(3, -5, 7) === true; xtype.none.isFalse(true, true, false, true) === false; xtype.any.isNan(7, 2.5, NaN, 0, -5) === true; xtype.any.isBlankString('Tom', 0, true, null, ' ') === true; xtype.any.isFloat(3, -5, 7) === false; xtype.any.isFalse(true, true, false, true) === true; xtype.some.isFloat(7, 2.5, NaN, 0, -5) === true; xtype.some.isString('Tom', 0, true, null, ' ') === true; xtype.some.isFloat(3, -5, 7) === false; xtype.some.isInteger(3, -5, 7) === false; // All integer, not some xtype.all.isFloat(7, 2.5, NaN, 0, -5) === true; xtype.all.isNonBlankString('hi', 'Tom', 'pi') === false; xtype.all.isFloat(3.1, -5.5, 7) === false; xtype.all.isNonZeroNumber(3, -5, 7) === true; xtype.isSingleCharString('g') === true; xtype.isNonEmptyObject({foo: 'bar'}) === true; xtype.isSingleElemArray(['foo']) === true; xtype.isFloat(2.50) === true; xtype.isPositiveNumber(-2.5) === false; xtype.isNan(5 / 'hi') === true; /* * --------------------------------------------------------------- * REGISTER A DERIVED TYPE THAT MATCHES ALL OF THE COMPONENT TYPES * --------------------------------------------------------------- */ // To register a new type with name 'non_negative_integer', that validates // when a data value matches both of the existing 'non_negative_number' and // 'integer' types: xtype.ext.registerType('non_negative_integer', { definition: 'non_negative_number, integer', matchMode: 'all' }); xtype.isNonNegativeInteger(value); xtype.is(value, 'non_negative_integer'); // To register a new type and also specify the corresponding names for the // type in other name schemes, the 'schemeAliases' property can be used. // For instance, to register the 'non_negative_integer' type also specifying // '-int-' as the name of the type in the 'compact' name scheme: xtype.ext.registerType('non_negative_integer', { definition: 'non_negative_number, integer', matchMode: 'all', schemeAliases: { compact: '-int-' } }); xtype.isNonNegativeInteger(value); xtype.is(value, '{@type:non_negative_integer:-int-}'); // The name of the new type can also be specified for several custom name // schemes as part of the type registration. For instance, the following also // specifies the type names for both the 'compact' and 'allcaps' name schemes: xtype.ext.registerType('non_negative_integer', { definition: 'non_negative_number, integer', matchMode: 'all', schemeAliases: { compact: '-int-', allcaps: 'NON_NEGATIVE_INTEGER' } }); /* * --------------------------------------------------------------- * REGISTER A DERIVED TYPE THAT MATCHES ANY OF THE COMPONENT TYPES * --------------------------------------------------------------- */ // To register a new type named 'flag' that validates when a data // value is either a positive integer or a single character string: xtype.ext.registerType('flag', { definition: 'positive_integer, single_char_string', // matchMode omitted because 'any' is the default }); xtype.isFlag(value); xtype.is(value, 'flag'); // But because only the 'definition' property is used in the 'flag' // custom type registration above, it can be simplified to use the // type expression string parameter format instead, which in this // case accomplishes exactly the same thing: xtype.ext.registerType('flag', 'positive_integer, single_char_string'); /* * ------------------------------ * REGISTER A SELF-VALIDATED TYPE * ------------------------------ */ // To register a type named 'social_security_number' that validates SSNs, // and with 'ssn' as the name of the type in the 'compact' name scheme: xtype.ext.registerType('social_security_number', { definition: { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); } }, schemeAliases: { compact: 'ssn' } }); xtype.isSocialSecurityNumber(value); xtype.is(value, '{@type:social_security_number:ssn}'); // To register it simply with a single name 'ssn' as both the default name // and name in any custom name schemes, then the registration can just be: xtype.ext.registerType('ssn', { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); } }); xtype.isSsn(value); xtype.is(value, 'ssn'); /* * ------------------------- * REGISTER AN INSTANCE TYPE * ------------------------- */ // To register an instance type constructor function, Product, // using the default name 'product' and with 'prod' as the name // of the type in the 'compact' name scheme: xtype.ext.registerType('product', { definition: Product, schemeAliases: { compact: 'prod' } }); xtype.isProduct(value); xtype.is(value, '{@type:product:prod}'); // To register it simply with a single name 'prod' as both the // default name and name in any custom name schemes, then the // simple function parameter format can be used: xtype.ext.registerType('prod', Product); xtype.isProd(value); xtype.is(value, 'prod'); /* * ------------------------------- * REGISTER MULTIPLE TYPES AT ONCE * ------------------------------- */ xtype.ext.registerType({ non_negative_integer: { // Derived type: match all definition: 'non_negative_number, integer', matchMode: 'all', schemeAliases: { compact: '-int-' } }, social_security_number: { // Self-validated type definition: { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); } }, schemeAliases: { compact: 'ssn' } }, flag: 'positive_integer, single_char_string', // Derived type: match any product: Product // Instance type }); xtype.introspect.typeIdToName(xtype.POSITIVE_INTEGER) === '{positive_integer}'; xtype.introspect.typeNameToId('{positive_integer}') === xtype.POSITIVE_INTEGER; xtype.introspect.typeComposition('{blank_string}') === ['{empty_string}', '{whitespace}']; // When a name scheme other than the default scheme is active xtype.setNameScheme('compact'); xtype(5) === 'int+'; // We can easily lookup the more descriptive default name // scheme equivalent of a type in the active name scheme: xtype.introspect.typeDefaultName('int+') === 'positive_integer'; // Useful for example, for a single value check, // to get the more descriptive default name without // switching out of the compact name scheme: xtype.introspect.typeDefaultName(xtype(5)) === 'positive_integer'; // Normally: xtype('abc') === '{multi_char_string}'; // The type names from the default name scheme are // friendlier, but still not very user-friendly: xtype.introspect.typeDefaultName(xtype('abc')) === 'multi_char_string'; // But using introspection's friendly names // produces much friendlier type descriptions // for user messaging and reporting: xtype.introspect.typeFriendlyName(xtype('abc')) === 'multiple character string'; // Another example: xtype(5/'a') === '{nan}'; xtype.introspect.typeDefaultName(xtype(5/'a')) === 'nan'; xtype.introspect.typeFriendlyName(xtype(5/'a')) === 'not a number';
{{methodGroup.name}} API
deprecated new
Requires Extension:   {{method.extension}}

Arguments No Arguments Type Description
Return
Argument: {{argumentDetail.name}}
Property Type Required Description
Method List
{{method.methodEnumeration[typeEnumGroup].name}}
Example
npm install xtypejs --save

{{contentItem.attributes.description}}

The following downloads are available for this release:

The official extensions below are provided as separate modules.

The official name schemes below are provided as separate modules. To learn more about name schemes, see using name schemes.

# npm: npm install xtypejs --save # npm from github: npm install git://github.com/lucono/xtypejs.git var xtype = require('xtypejs'); // node.js and CommonJS require(['xtype'], function(xtype) { // requirejs and AMD // Use xtype here }); xtype(-2.5) === '{negative_float}'; // Value is number, negative and float xtype(' ') === '{whitespace}'; // Value is string and blank xtype({}) === '{empty_object}'; // Value is object and is empty xtype(['hi']) === '{single_elem_array}'; // Value is array, has exactly one element xtype.type(null) === '{null}'; xtype.type(undefined) === '{undefined}'; xtype.type(NaN) === '{nan}'; xtype.type([]) === '{array}'; xtype.type({}) === '{object}'; xtype.type(new Date()) === '{date}'; xtype.type(function() {}) === '{function}'; xtype.type(/ab+c/i) === '{regexp}'; xtype.type(new Error('No!')) === '{error}'; xtype.type(Symbol()) === '{symbol}'; xtype.type('Hi') === '{string}'; xtype.type(new String('Hi')) === '{string}'; xtype.type(25) === '{number}'; xtype.type(new Number(25)) === '{number}'; xtype.type(true) === '{boolean}'; xtype.type(new Boolean(true)) === '{boolean}'; xtype.is(data, '{{non_empty_object, single_elem_array, positive_integer}}'); xtype.is(value, Product); xtype.is(value, ['{multi_char_string}', '{positive_integer}', Product]); switch (xtype.which(value, ['{multi_char_string}', '{positive_integer}', Product])) { case '{multi_char_string}': // value is a multi-character string case '{positive_integer}': // value is a positive integer case Product: // value is a Product object } // Product instance type referenced using the constructor function: xtype.is(value, ['str2+', 'int+', Product]); // However, registering the instance type gives it a type name: xtype.ext.registerType('product', Product); // The type name can then be used as the Instance type in type expressions: xtype.is(value, '{{multi_char_string, positive_integer,}} product'); // Verify if 'flag' variable is a single character string: xtype.is(flag, '{single_char_string}'); xtype.is(flag, xtype.SINGLE_CHAR_STRING); xtype.isSingleCharString(flag); // Verify if 'flag' variable is a single character string or positive number value: xtype.is(flag, '{{single_char_string, positive_number}}'); xtype.is(flag, xtype.SINGLE_CHAR_STRING | xtype.POSITIVE_NUMBER); xtype.is(flag, ['{single_char_string}', xtype.POSITIVE_NUMBER]); xtype.isSingleCharString('g') === true; xtype.isNonEmptyObject({foo: 'bar'}) === true; xtype.isSingleElemArray(['foo']) === true; xtype.isFloat(2.50) === true; xtype.isPositiveNumber(-2.5) === false; xtype.isNan(5 / 'hi') === true; xtype.none.isNan(7, 2.5, NaN, 0, -5) === false; xtype.any.isZero(7, 2.5, NaN, 0, -5) === true; xtype.all.isPositiveInteger(3, 5.1, 7) === false; xtype.some.isFloat(3, 5.5, 7) === true; // Some but not all are float xtype.some.isFloat(2.5, 8.5, 2.1) === false; // All are float, not some xtype.all.isNonZeroNumber(4, -20, 8.5) === true; // They can also take a single array of the values to be checked: var values = ['Tom', 0, true, null, ' ']; xtype.any.isNothing(values) === true; // null is of 'nothing' type xtype.all.isPrimitive(values) === false; // null is of 'nothing' type, not 'primitive' xtype.none.isBlankString(values) === false; xtype.some.isTrue(values) === true; switch (xtype.which(value, '{{multi_char_string, positive_integer, nothing}}')) { case '{multi_char_string}': // Fetch and display product with value as the product name string case '{positive_integer}': // Fetch and display product with value as the product Id number case '{nothing}': // value is null or undefined, handle no value provided default: // value is present but not any of expected 'types', do error } xtype.isTrue(23.5) === false; // Truthy but not boolean xtype.isTrue(new MyProduct()) === false; // Any type can be checked xtype.isTrue('true') === false; // String is not boolean xtype.isFalse('false') === false; // String is not boolean xtype.isTrue(true) === true; // Primitive true is actual true xtype.isTrue(new Boolean(true)) === true; // Object true is actual true xtype.isFalse(false) === true; // Primitive false is actual false xtype.isFalse(new Boolean(false)) === true; // Object false is actual false xtype.isSingleCharString('t') === true; xtype.isSingleCharString(' g ') === true; xtype.isSingleCharString(' ') === false; xtype.isSingleCharString('q1') === false; xtype.isSingleCharString(new String(' z ')) === true; // Regular type checking: typeof 'foo' === 'string'; typeof new String('foo') === 'object'; // Type checking with xtypejs: xtype.type('foo') === '{string}'; xtype.type(new String('foo')) === '{string}'; xtype.type(25) === '{number}'; xtype.type(new Number(25)) === '{number}'; xtype.isZero(0) === true; xtype.isZero(new Number(0)) === true; /* * ------------------------------------------------------------- * CREATING DERIVED TYPE THAT MATCHES ALL OF THE COMPONENT TYPES * ------------------------------------------------------------- */ // To create a new type named 'non_negative_integer', that validates // when a data value matches both of the existing 'non_negative_number' // and 'integer' types: xtype.ext.registerType('non_negative_integer', { definition: 'non_negative_number, integer', matchMode: 'all' }); // The type expression value of the 'definition' property may include any // existing types, including built-in types, registered instance types and // other already registered custom and derived types. However, it must use the // default type names of the component types and not those of any name scheme that // was registered in xtypejs, such as for example, the 'compact' name scheme. /* * ------------------------------------------------------------- * CREATING DERIVED TYPE THAT MATCHES ANY OF THE COMPONENT TYPES * ------------------------------------------------------------- */ // The value of the 'matchMode' property can be 'all' to match all the // component types, or 'any' (the default when omitted) to match any // of the component types. For instance, to register a new type named // 'app_flag' that validates when a data value is either a positive integer // or a single character string: xtype.ext.registerType('app_flag', { definition: 'positive_integer, single_char_string', matchMode: 'any' }); // However, because 'any' is the default value for matchMode, // for creating our 'app_flag' type we can just have: xtype.ext.registerType('app_flag', { definition: 'positive_integer, single_char_string' }); // But again, because only the 'definition' attribute is used in the // type registration, we can simply have: xtype.ext.registerType('app_flag', 'positive_integer, single_char_string'); /* * ---------------------------------------------------------------- * PROVIDING TYPE NAMES FOR THE CUSTOM TYPE IN VARIOUS NAME SCHEMES * ---------------------------------------------------------------- */ // Using the 'schemeAliases' key, we can provide the names to be used // for the newly registered type for various custom name schemes that // are registered with xtypejs: xtype.ext.registerType('app_flag', { definition: 'positive_integer, single_char_string', schemeAliases: { compact: 'flag' } }); /* * --------------------------------- * USE NEWLY REGISTERED DERIVED TYPE * --------------------------------- */ // After registration of the new types, we can now use them in type checking: xtype.is(value, '{@type:non_negative_integer:-int-}'); xtype.is(value, '{@type:app_flag:flag}'); // New 'is' methods with the camel-cased name of the new types will // also become available on the xtype module for checking the types: xtype.isNonNegativeInteger(value); xtype.isAppFlag(value); // To create a type named 'social_security_number' for validating SSNs: xtype.ext.registerType('social_security_number', { definition: { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); }, schemeAliases: { compact: 'ssn' } } }); // After registration of the new type, we can now use it in type checking: xtype.is(value, '{@type:social_security_number:ssn}'); xtype.isSocialSecurityNumber(value); // However, if we just wanted to register it simply with a single name 'ssn' as // both the default and compact names, then the registration could just be: xtype.ext.registerType('ssn', { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); } }); xtype.is(value, 'ssn'); xtype.isSsn(value); // To register an instance type constructor function, Product, // using the default name 'product' and the name 'prod' for // the 'compact' name scheme: xtype.ext.registerType('product', { definition: Product, schemeAliases: { compact: 'prod' } }); // After registration of the instance type, we can then use it in type // checking and in type expressions, like with most other types: xtype.isProduct(value); xtype.is(value, '{@type:product:prod}'); xtype.is(value, '{{multi_char_string, positive_integer,}} {@type:product:prod}'); xtype.options.setNameScheme({ positive_number: 'pos_num', empty_object: 'emp_obj', blank_string: 'bl_str' /* More entries */ }); xtype({}) === 'emp_obj'; // empty_object is 'emp_obj' in new scheme xtype(25) === 'pos_num'; // positive_integer is 'pos_num' in new scheme xtype(' ') === 'bl_str'; // blank_string is 'bl_str' in new scheme xtype.is({}, 'emp_obj') === true; xtype.is(25, 'pos_num') === true; xtype.is(' ', 'bl_str') === true; // With the regular 'default' name scheme: xtype({}) === 'empty_object'; xtype(25) === 'positive_integer'; xtype.is({}, 'empty_object') === true; xtype.is(25, 'positive_integer') === true; // Switch to the 'compact' name scheme: var compactNameScheme = require('xtypejs-name-scheme-compact'); xtype.ext.registerNameScheme('compact', compactNameScheme); xtype.options.setNameScheme('compact'); xtype({}) === 'obj0'; // Compact scheme uses 'obj0' for 'empty_object' xtype(25) === 'int+'; // Compact scheme uses 'int+' for 'positive_integer' xtype.is({}, 'obj0') === true; xtype.is(25, 'int+') === true; var customNameScheme = { positive_number: 'pos_num', empty_object: 'emp_obj', blank_string: 'bl_str' /* More entries */ }; xtype.ext.registerNameScheme('my_custom_scheme', customNameScheme); // The custom scheme is now internally registered // and can now be referenced by name: xtype.options.setNameScheme('my_custom_scheme'); xtype({}) === 'emp_obj'; xtype(25) === 'pos_num'; xtype(' ') === 'bl_str'; xtype.is({}, 'emp_obj') === true; xtype.is(25, 'pos_num') === true; xtype.is(' ', 'bl_str') === true; xtype.options.setNameScheme('default'); xtype.is(value, '{single_char_string},{positive_number}'); xtype.is(value, '{single_char_string}, {positive_number}'); xtype.is(value, '{single_char_string}|{positive_number}'); xtype.is(value, '{single_char_string} | {positive_number}'); xtype.is(value, '{single_char_string} {positive_number}'); xtype.options.setDelimiterPattern('/'); xtype.is(0, '{zero} / {positive_number}') === true; xtype.is(25, '{zero} / {positive_number}') === true; xtype.is(-3, '{zero} / {positive_number}') === false; // Using a different pattern to also allow the comma character: xtype.options.setDelimiterPattern('[/,]'); xtype.is(25, '{zero}, {positive_number} / {float}') === true; // The 'none' type xtype.isNone(25) === false; xtype.isNone(['hi', 5]) === false; xtype.isNone(undefined) === false; xtype.not.isNone('hello') === true; // true for any value xtype.all.isNone('hi', 5, true) === false; // false for any list of values xtype.some.isNone(null, 25, false) === false; // false for any list of values xtype.any.isNone(null, 25, false) === false; // false for any list of values xtype.none.isNone(null, 25, false) === true; // true for any list of values // The 'any' type xtype.isAny(25) === true; xtype.isAny(['hi', 5]) === true; xtype.isAny(undefined) === true; xtype.not.isAny('hello') === false; // false for any value xtype.all.isAny('hi', 5, true) === true; // true for any list of values xtype.some.isAny(null, 25, false) === false; // false for any list of values xtype.any.isAny(null, 25, false) === true; // true for any list of values xtype.none.isAny(null, 25, false) === false; // false for any list of values // The 'any' type can be temporarily added to a validating type expression as a // switch to temporarily make it fully permissive, therefore accepting all values: xtype.is(25, '{object}') === false; xtype.is(25, '{{object, any}}') === true; // allows any value to pass validation var validNumber = 5; // Valid number value var nanValue = (5 / 'a'); // NaN from invalid numeric computation var boxedNanValue = new Number(nanValue); // Boxed Number object having NaN value /* * ------------------- * Vanilla JavaScript: * ------------------- */ typeof validNumber === 'number'; typeof nanValue === 'number'; // NaN is also of 'number' type Number.isNaN(boxedNanValue) === false; // Boxed NaN Number not identified as NaN /* * -------- * xtypejs: * -------- */ xtype.type(validNumber) === 'number'; xtype.type(nanValue) === 'nan'; // NaN is not 'number' type xtype.isNan(boxedNanValue) === true; // Boxed NaN Number also identified as 'nan' /* * ---------------------------------------- * EXAMPLE: USER-FRIENDLY TYPE DESCRIPTIONS * FOR REPORTING AND USER MESSAGING * ---------------------------------------- */ // Normally: xtype('abc') === '{multi_char_string}'; // The type names from the default name scheme are // friendlier, but still not very user-friendly: xtype.introspect.typeDefaultName(xtype('abc')) === 'multi_char_string'; // But using introspection's friendly names // produces much friendlier type descriptions // for user messaging and reporting: xtype.introspect.typeFriendlyName(xtype('abc')) === 'multiple character string'; // Another example: xtype(5/'a') === '{nan}'; xtype.introspect.typeDefaultName(xtype(5/'a')) === 'nan'; xtype.introspect.typeFriendlyName(xtype(5/'a')) === 'not a number'; /* * ------------------------------------- * EXAMPLE: VALIDATE USER-SUPPLIED INPUT * ------------------------------------- */ // Some configured validation type var allowedInputType = '{integer}'; // Get user or other input to be validated var inputValue = getUserInput(); // --- WITHOUT Introspection --- if (xtype.not.is(inputValue, allowedInputType)) { showMessage('Input must be ' + allowedInputType); // shows: 'Input must be {integer}' } // --- WITH Introspection --- var allowedSubTypes = xtype.introspect.typeComposition(allowedInputType), friendlyTypeDescription = xtype.introspect.typeFriendlyName(allowedSubTypes); if (xtype.not.is(inputValue, allowedInputType)) { showMessage('Input must be either ' + friendlyTypeDescription); // shows: 'Input must be either zero, positive integer, negative integer' // (Type information is more descriptive and informative for the user) } /* * ---------------------------------------------------------- * This kind of introspection is even more valuable when * working with derived or other custom types. See more of * the introspection functions under the API tab. * ---------------------------------------------------------- */ var otherName = xtype.noConflict(); otherName.isPositiveInteger(5) === 'true'; // otherName is now xtypejs var version = xtype.VERSION; // Gives version of xtype library
function searchEmployees(value) { if (typeof value === 'string') { if (value.trim().length > 1) { return EmployeeDB.searchByName(value); } else if (value.trim().length === 1) { return EmployeeDB.searchByMiddleInitial(value); } else { return { error: 'Invalid search value supplied' }; } } else if (typeof value === 'object' && value !== null) { if (Object.keys(value).length === 1) { return EmployeeDB.searchByFieldValuePair(value); } else if (Object.keys(value).length > 1) { return { error: 'Search by multiple fields not supported' }; } else { return { error: 'Invalid search value supplied' }; } } else if (typeof value === 'number') { if (!isNaN(value) && isFinite(value) && value > 0 && value % 1 === 0) { return EmployeeDB.searchByEmployeeNumber(value); } else { return { error: 'Invalid employee number supplied' }; } } else if (typeof value === 'undefined' || value === null) { return { error: 'No search value supplied' }; } else { return { error: 'Invalid search value supplied' }; } } function searchEmployees(value) { switch (xtype.which(value, '{{multi_char_string, single_char_string, positive_integer, single_prop_object, multi_prop_object, number, nothing}}')) { case '{multi_char_string}': return EmployeeDB.searchByName(value); case '{single_char_string}': return EmployeeDB.searchByMiddleInitial(value); case '{positive_integer}': return EmployeeDB.searchByEmployeeNumber(value); case '{single_prop_object}': return EmployeeDB.searchByFieldValuePair(value); case '{multi_prop_object}': return { error: 'Search by multiple fields not supported' }; case '{number}': return { error: 'Invalid employee number supplied' }; case '{nothing}': return { error: 'No search value supplied' }; default: return { error: 'Invalid search value supplied' }; } } xtype.ext.registerType('ssn', { validator: function(val) { return typeof val === 'string' && /^\d{3}-\d{2}-\d{4}$/.test(val); } }); function searchEmployees(value) { switch (xtype.which(value, '{{positive_integer, ssn, multi_char_string}}')) { case '{positive_integer}': return EmployeeDB.searchByEmployeeNumber(value); case 'ssn': return EmployeeDB.searchBySSN(value); case '{multi_char_string}': return EmployeeDB.searchByName(value); default: return { error: 'Invalid search value supplied' }; } }
go from this..
..to concise performant readable validation
and, even add custom validation types of your own
var xtype = require('xtypejs'); var xtype = require('xtypejs'); var compactScheme = require('xtypejs-name-scheme-compact'); xtype.ext.registerNameScheme('compact', compactScheme); xtype.options.setNameScheme('compact'); var xtype = require('xtypejs'); var customTypes = require('xtypejs-extension-custom-types'); xtype.ext.registerExtension(customTypes); var xtype = require('xtypejs'); var compactScheme = require('xtypejs-name-scheme-compact'); var camelScheme = require('xtypejs-name-scheme-camel'); var shortScheme = require('xtypejs-name-scheme-shortened'); var shortCamelScheme = require('xtypejs-name-scheme-shortened-camel'); xtype.ext.registerNameScheme('compact', compactScheme); xtype.ext.registerNameScheme('camel', camelScheme); xtype.ext.registerNameScheme('shortened', shortScheme); xtype.ext.registerNameScheme('shortenedCamel', shortCamelScheme); var xtype = require('xtypejs'); var customTypes = require('xtypejs-extension-custom-types'); var introspection = require('xtypejs-extension-introspection'); var autoCamel = require('xtypejs-extension-autocamel-name-scheme'); xtype.ext.registerExtension(customTypes, introspection, autoCamel); var compactScheme = require('xtypejs-name-scheme-compact'); var camelScheme = require('xtypejs-name-scheme-camel'); var shortScheme = require('xtypejs-name-scheme-shortened'); var shortCamelScheme = require('xtypejs-name-scheme-shortened-camel'); xtype.ext.registerNameScheme('compact', compactScheme); xtype.ext.registerNameScheme('camel', camelScheme); xtype.ext.registerNameScheme('shortened', shortScheme); xtype.ext.registerNameScheme('shortenedCamel', shortCamelScheme); var xtype = require('xtypejs'); var customTypes = require('xtypejs-extension-custom-types'); var compactScheme = require('xtypejs-name-scheme-compact'); xtype.ext.registerExtension(customTypes); xtype.ext.registerNameScheme('compact', compactScheme); xtype.options.setNameScheme('compact');
{{typeGroup.name}} Types

category {{type.category}} type
derived {{(type.derived === true || type.derivation.length > 0) ? 'yes' : 'no'}}
derivation Match Any: {{compositeTypeName}}
Example