types.js
A tiny (1.8kb), but essential Javascript type checking library.
Especially in non-typed scripting languages like Javascript, proper manual type checking is crucial.
Because type checking in Javascript is such a mess, I decided to make a library with clear standards
I can build upon.
A few quick examples with types.js:
_.typeof( [] );
_.typeof( null );
_.typeof( /someregexp/ );
_.typeof( parseInt('Not A Number!') );
_.forceString( 123 );
_.allDefined( 'good', false, null );
_.hasObject( 'not', 'really' );
Force!
Force some value to be of some type. A replacement value can be given in case value is invalid, without replacement
a default literal of the forced type will be returned.
var left= '500px';
var callback= null;
if ( typeof left === 'string' ){
left= parseInt( left, 10 );
}
if ( left !== left || typeof left !== 'number' )
left= 100;
}
if ( typeof callback !== 'function' ){
callback= function(){}
}
callback( left );
left= _.forceNumber( left, 100 );
_.forceFunction( callback )( left );
Check it out, it's sweet! I've added force to types.js because I use it all the time and it seems to belong in here.
For use with node.js you can install with npm install types.js
Basic usage:
force'Type' Forces a value to be of a given type, and returns that value, a replacement, or it's literal default.
is'Type' and not'Type' are useful for single argument type checking.
all'Type' is useful for checking if all given arguments are of a certain type.
has'Type' is useful for checking if one or more arguments are of a certain type.
typeof Returns a lowercase string representation of the type of the argument value, according to types.js type-definitions.
some more examples:
var _= Types;
var _= require( 'types.js' );
var x;
x= _.forceString();
x= _.forceString( null, 'ok' );
x= _.forceString( null, [1, 2, 3] );
x= _.forceString(33);
x= _.forceNumber('35px');
x= _.forceNumber( true, function(){} );
x= _.forceBoolean('35px');
x= _.forceArray("you'll get an array");
var func= null;
_.forceFunction( func )( 'arguments for func, or replacement' );
x= _.isDefined()
x= _.isString( 'Hello types.js!' );
x= _.isString( 23456 );
x= _.isBoolean( false );
x= _.isArray( [1,2,3] );
x= _.isObject( [1,2,3] );
x= _.isObject( /myRegExp/g );
x= _.isNaN( parseInt('generate NaN') );
x= _.notNull('');
x= _.notUndefined( undefined );
x= _.isDefined( null );
x= _.allString( '', " ", 'with text' );
x= _.allString( '', ' ', 'with text', 123 );
x= _.allStringOrNumber( '', ' ', 'with text', 123 );
x= _.allObject( { key: 'nice' }, [], /regexp/ig );
x= _.allArray( [1,2,3], [{}], new RegExp('stop') );
x= _.allArray( [1,2,3], [{}], [false, true] );
x= _.hasString( 123, { value: 'nice' }, ['?'] );
x= _.hasStringOrNumber( [1,2], /reg/, 'true' )
x= _.hasFunction( 123, { value: 'nice' }, function(){} );
x= _.hasUndefined( 'render false!', 123, null );
x= _.hasUndefined( 'render true!', 123, undefined );
x= _.typeof( [1,2,3] );
x= _.typeof( null );
x= _.typeof( parseInt('generate NaN') );
x= _.typeof( new Date() );
API
Types.parseIntBase
<Number> parseIntBase= 10
Holds the Radix used by forceNumber, defaults to decimals. Can be set to valid radixes for parseInt(). Note that once set, all
following forceNumber calls will use the new Radix.
_.parseIntBase= 0xf;
var nr= _.forceNumber( 'a linefeed' );
console.log( nr );
Types.forceBoolean
<String> Types.forceBoolean( value, replacement )
Returns value if value is of type Boolean. Otherwise it will try to convert value to be a Boolean. If that
fails too, replacement will be tested for, or converted to, 'boolean' if possible. If that fails, the default
types.js boolean literal is returned: a Boolean false
var assert= _.forceBoolean( 'Only a true true returns true' );
console.log( assert );
var assert= _.forceBoolean( NaN != NaN );
console.log( assert );
Types.forceString, Types.forceArray, Types.forceObject
Just like forceBoolean, only applying the type denoted by the method name. See the force'Type' literals for
the different methods below.
Types.forceNumber
<Number> forceNumber( <String>/<Number> value, <String>/<Number> replacement )
Returns value if it is a Number or convertable to a Number. Returns replacement if value is invalid or not convertable.
Returns a Number object with a .void property set to true if no valid value and replacement were given or no conversion was possible.
You can check yourNumber.void to see if yourNumber is set to a valid number. If .void is true, yourNumber is not set to a
number, but to a Number object which is ready for mathemetical operation, and defaults to 0.
Types.typeof( Types.forceNumber() );
returns 'number', as it is a Number and you can use it as number.
Example: make a numberFilter for arguments with the new forceNumber:
function numberFilter(){
var numbers= [];
for( var arg in arguments ){
var value= _.forceNumber( arguments[arg] );
if( value.void )
continue;
numbers.push( value );
}
return numbers;
}
function someFunc(){
return numberFilter.apply( this, arguments );
}
console.log( someFunc('ignore', 1, 'the', 2, 'strings!', 3) );
console.log( someFunc('1 but', '2 not', '3 unconditional!') );
Types.forceFunction
<Function> Types.forceFunction( <Function> func, <Function> replacement )
Returns func if it is a Function. So you can call your function with Types.forceFunction(func)( args ). If it is
a Function, it will call and pass the given arguments.
forceFunction will not try/catch func for other failures.
If func or replacement are not of type Function, a dummy function will be called returning undefined.
var showAuthor= function( name ){
console.log( 'Author: '+ _.forceString(name) );
};
_.forceFunction( showAuthor )( 'Dennis Raymondo' );
var showAuthor= null;
_.forceFunction( showAuthor, function(name){
console.log( 'Could not call showAuthor! Arguments: '+ _.forceString(name) );
})( 'Dennis Raymondo' );
Types.typeof
<String> Types.typeof( value )
Returns a lowercase string representation of the type of value, according to types.js types. See all types.js
type-definitions below.
var nan= parseInt( 'damn NaN!' );
console.log( _.typeof(nan) );
Types.isBoolean
<Boolean> Types.isBoolean( value )
Returns true if the given argument is a Boolean true or false
console.log( _.isBoolean(false) );
Types.notBoolean
<Boolean> Types.isBoolean( value )
Returns true if the given argument is not a Boolean true or false
console.log( _.notBoolean('not a Boolean') );
Types.hasBoolean
<Boolean> Types.hasBoolean( values, [value1, ..., valueN])
Returns true if any of the given arguments is a Boolean true or false
console.log( _.hasBoolean('the third', null, false) );
Types.allBoolean
<Boolean> Types.allBoolean( values, [value1, ..., valueN])
Returns true only if all given arguments are either a Boolean true or false
console.log( _.allBoolean(false, null, true) );
All remaining methods are equal to the last four above, except for that they differ in the type being checked. The complete
list of all these methods:
not | is | has | all |
---|
notBoolean | isBoolean | hasBoolean | allBoolean |
notString | isString | hasString | allString |
notNumber | isNumber | hasNumber | allNumber |
notStringOrNumber | isStringOrNumber | hasStringOrNumber | allStringOrNumber |
notObject | isObject | hasObject | allObject |
notArray | isArray | hasArray | allArray |
notFunction | isFunction | hasFunction | allFunction |
notRegexp | isRegexp | hasRegexp | allRegexp |
notDate | isDate | hasDate | allDate |
notNull | isNull | hasNull | allNull |
notUndefined | isUndefined | hasUndefined | allUndefined |
notDefined | isDefined | hasDefined | allDefined |
notNaN | isNaN | hasNaN | allNaN |
types.js type definitions:
'boolean', 'string', 'number', 'object', 'array', 'function', 'regexp', 'date', 'null', 'undefined', 'nan'
force'Type' method and default literals
<'Type'> force'Type'( <any type> value, <'Type'> replacement )
The literals returned by default:
forceBoolean | forceString | forceNumber | forceObject | forceArray | forceFunction |
---|
false | '' | 0 (Number) | {} | [] | function(){} |
change log
1.3.9
Removed 'unknown' from types.js type definitions. It was meant to be like a final state, for if no other matching type could
be found, but in the codebase as it is now, that state can never be reached.. If Javascript ever invents a brand new type,
types.js will return 'defined' on that one if I would not take action and implement support for it.
Updated the readme.
1.3.5
Changed:
-
forceNumber doesn't return 0 by default anymore. It now returns a Number object with a .void property which is set to
true if no valid Number was given or no conversion was possible.
Just use: _.forceNumber( value, 0 );
to return a 0 as replacement, it only is not default anymore.
I made this change because I wanted to be able to check if forceNumber was successful. Just a 0 can be very misleading and
a source for bugs. NaN is a failure IMO, so I made a kind of replacement feature in forceNumber.
You can now check for yourNumber.void to see if it is set. If .void is true, yourNumber is a Number object which is ready for
mathemetical operation, and defaults to 0, this in contrast with NaN, which is almost totally unusable.
example:
var nr= forceNumber();
console.log( nr.void );
console.log( nr );
console.log( 0 + nr );
( nr.void )
? console.log( 'void?', nr+= 36/ 4 );
: console.log( nr );
etc..
Updated:
- Jasmine tests for forceNumber and isDefined
- speed optimization for isObject
1.3.1
Added:
-
change log in the readme, more convenient overview of changes.
-
is/not/has/allDefined
Now you can: if (_.isDefined(value) )
instead of if (_.notUndefined(value) )