check-types.js
A little JavaScript library
for asserting types
and values,
with zero dependencies.
Why would I want that?
Writing explicit conditions
in your functions
to check arguments
and throw errors
is a task that
swiftly becomes tiresome
and adds complexity
to your codebase.
The purpose of check-types.js
is to remove this burden
from JavaScript application developers
in an efficient and robust manner,
abstracted by a simple API.
How little is it?
25 kb unminified with comments, 7.4 kb minified, 2.5 kb minified + gzipped.
How do I install it?
Via npm:
npm i check-types --save
Or if you just want the git repo:
git clone git@gitlab.com:philbooth/check-types.js.git
How do I use it?
Loading the library
If you are running in Node.js
or a CommonJS environment,
you can require
check-types like so:
const check = require('check-types');
It also the supports
the AMD-style format
preferred by Require.js.
If you are
including check-types.js
with an HTML <script>
tag,
or neither of the above environments
are detected,
it will export the interface globally as check
.
Calling the exported functions
Once you've loaded the library
in your application,
a whole bunch of functions are available
to call.
Most of the functions
are predicates,
which can be executed
in a number of different contexts:
-
check.xxx(thing)
:
These functions are basic predicates,
returning true or false
depending on the type and value of thing
.
-
check.not.xxx(thing)
:
The not
modifier
negates predicates,
returning true
if the predicate returns false
and false
if the predicate returns true
.
It is also itself a function,
which simply returns
the negation of
its argument.
-
check.maybe.xxx(thing)
:
The maybe
modifier
tweaks predicates to
return true
if thing
is null
or undefined
,
otherwise their normal result
is returned.
It is also itself a function,
which returns true
when its argument is null
or undefined
,
otherwise it returns its argument.
-
check.assert.xxx(thing, message)
:
The assert
modifier
changes predicates
to throw when their result is false
,
otherwise it returns thing
.
It can be applied
to the not
and maybe
modifiers
using the forms
check.assert.not.xxx(thing, message)
and
check.assert.maybe.xxx(thing, message)
.
It is also itself a function,
which simply throws
when its argument is false.
-
check.array.of.xxx(thing)
:
The array.of
modifier
first checks that
it is operating on an array
and then applies
the modified predicate
to each item
of the array.
If the predicate fails
for any item,
it returns false
,
otherwise it returns true
.
It can also be prefixed
by other modifiers,
so check.maybe.array.of
,
check.not.array.of
,
check.assert.array.of
,
check.assert.maybe.array.of
and
check.assert.not.array.of
all work
as you would expect
them to.
-
check.arrayLike.of.xxx(thing)
:
The arrayLike.of
modifier
is synonymous with array.of
,
except it operates on array-like objects.
-
check.iterable.of.xxx(thing)
:
The iterable.of
modifier
is synonymous with array.of
,
except it operates on iterables.
-
check.object.of.xxx(thing)
:
The object.of
modifier
is synonymous with array.of
,
except it operates on an object's properties.
Additionally, there are some batch operations
to help you apply predicates
to each value
of an array or object.
These are implemented by
check.map
,
check.any
and
check.all
.
General predicates
-
check.equal(thing, thang)
:
Returns true
if thing === thang
,
false
otherwise.
-
check.null(thing)
:
Returns true
if thing
is null
,
false
otherwise.
-
check.undefined(thing)
:
Returns true
if thing
is undefined
,
false
otherwise.
-
check.assigned(thing)
:
Returns true
if thing
is not
null
or undefined
,
false
otherwise.
-
check.primitive(thing)
:
Returns true
if thing
is a primitive type,
false
otherwise.
Primitive types are
null
, undefined
, booleans, numbers, strings and symbols.
-
check.hasLength(thing, value)
:
Returns true
if thing
has a length property
that equals value
,
false
otherwise.
String predicates
-
check.string(thing)
:
Returns true
if thing
is a string,
false
otherwise.
-
check.emptyString(thing, options)
:
Returns true
if thing
is the empty string,
false
otherwise.
-
check.nonEmptyString(thing, options)
:
Returns true
if thing
is a non-empty string,
false
otherwise.
-
check.contains(string, substring)
:
Returns true
if string
contains substring
,
false
otherwise.
-
check.in(substring, string)
:
Returns true
if substring
is in string
,
false
otherwise.
-
check.match(string, regex)
:
Returns true
if string
matches regex
,
false
otherwise.
Number predicates
-
check.number(thing)
:
Returns true
if thing
is a number,
false
otherwise.
Note that
NaN
,
Number.POSITIVE_INFINITY
and
Number.NEGATIVE_INFINITY
are not considered numbers here.
-
check.integer(thing)
:
Returns true
if thing
is an integer,
false
otherwise.
-
check.float(thing)
:
Returns true
if thing
is a non-integer number,
false
otherwise.
-
check.zero(thing)
:
Returns true
if thing
is zero,
false
otherwise.
-
check.one(thing)
:
Returns true
if thing
is one,
false
otherwise.
-
check.infinity(thing)
:
Returns true
if thing
is positive or negative infinity,
false
otherwise.
-
check.greater(thing, value)
:
Returns true
if thing
is a number
greater than value
,
false
otherwise.
-
check.greaterOrEqual(thing, value)
:
Returns true
if thing
is a number
greater than or equal to value
,
false
otherwise.
-
check.less(thing, value)
:
Returns true
if thing
is a number
less than value
,
false
otherwise.
-
check.lessOrEqual(thing, value)
:
Returns true
if thing
is a number
less than or equal to value
,
false
otherwise.
-
check.between(thing, a, b)
:
Returns true
if thing
is a number
between a
and b
(excluding a
and b
),
false
otherwise.
The arguments a
and b
may be in any order,
it doesn't matter
which is greater.
-
check.inRange(thing, a, b)
:
Returns true
if thing
is a number
in the range a
.. b
(including a
and b
),
false
otherwise.
The arguments a
and b
may be in any order,
it doesn't matter
which is greater.
-
check.positive(thing)
:
Returns true
if thing
is a number
greater than zero,
false
otherwise.
-
check.negative(thing)
:
Returns true
if thing
is a number
less than zero,
false
otherwise.
-
check.odd(thing)
:
Returns true
if thing
is an odd number,
false
otherwise.
-
check.even(thing)
:
Returns true
if thing
is an even number,
false
otherwise.
Boolean predicates
check.boolean(thing)
:
Returns true
if thing
is a boolean,
false
otherwise.
Object predicates
-
check.object(thing)
:
Returns true
if thing
is a plain-old JavaScript object,
false
otherwise.
-
check.emptyObject(thing)
:
Returns true
if thing
is an empty object,
false
otherwise.
-
check.nonEmptyObject(thing)
:
Returns true
if thing
is a non-empty object,
false
otherwise.
-
check.thenable(thing)
:
Returns true
if thing
has a then
method,
false
otherwise.
-
check.instanceStrict(thing, prototype)
:
Returns true
if thing
is an instance of prototype
,
false
otherwise.
-
check.instance(thing, prototype)
:
Returns true
if thing
is an instance of prototype
,
false
otherwise.
Falls back to testing
constructor.name
and Object.prototype.toString
if the instanceof
test fails.
-
check.contains(object, value)
:
Returns true
if object
contains value
,
false
otherwise.
-
check.in(value, object)
:
Returns true
if value
is in object
,
false
otherwise.
-
check.containsKey(object, key)
:
Returns true
if object
contains key key
,
false
otherwise.
-
check.keyIn(key, object)
:
Returns true
if key key
is in object
,
false
otherwise.
-
check.like(thing, duck)
:
Duck-typing checker.
Returns true
if thing
has all of the properties of duck
,
false
otherwise.
-
check.identical(thing, thang)
:
Deep equality checker.
Returns true
if thing
has all of the same values as thang
,
false
otherwise.
Array predicates
-
check.array(thing)
:
Returns true
if thing
is an array,
false
otherwise.
-
check.emptyArray(thing)
:
Returns true
if thing
is an empty array,
false
otherwise.
-
check.nonEmptyArray(thing)
:
Returns true
if thing
is a non-empty array,
false
otherwise.
-
check.arrayLike(thing)
:
Returns true
if thing
has a numeric length property,
false
otherwise.
-
check.iterable(thing)
:
Returns true
if thing
implements the iterable protocol,
false
otherwise.
In pre-ES6 environments,
this predicate falls back
to arrayLike
behaviour.
-
check.contains(array, value)
:
Returns true
if array
contains value
,
false
otherwise.
-
check.in(value, array)
:
Returns true
if value
is in array
,
false
otherwise.
Date predicates
check.date(thing)
:
Returns true
if thing
is a valid date,
false
otherwise.
Function predicates
-
check.function(thing)
:
Returns true
if thing
is a function,
false
otherwise.
-
check.throws(() => thing())
:
Returns true
if thing
is a function that throws,
false
otherwise.
Modifiers
-
check.not(value)
:
Returns the negation
of value
.
-
check.not.xxx(...)
:
Returns the negation
of the predicate.
-
check.maybe(value)
:
Returns true
if value
is null
or undefined
,
otherwise it returns value
.
-
check.maybe.xxx(...)
:
Returns true
if thing
is null
or undefined
,
otherwise it propagates
the return value
from its predicate.
-
check.array.of.xxx(value)
:
Returns true
if value
is an array
and the predicate is true
for every item.
Also works with the not
and maybe
modifiers.
-
check.arrayLike.of.xxx(thing)
:
The arrayLike.of
modifier
is synonymous with array.of
,
except it operates on array-like objects.
-
check.iterable.of.xxx(thing)
:
The iterable.of
modifier
is synonymous with array.of
,
except it operates on iterables.
-
check.object.of.xxx(thing)
:
The object.of
modifier
is synonymous with array.of
,
except it operates on an object's properties.
-
check.assert(value, message, ErrorType)
:
Throws a TypeError
if value
is falsy,
otherwise it returns value
.
message
and ErrorType
are optional arguments
that control
the message and type
of the thrown error object.
-
check.assert.xxx(...)
:
Throws a TypeError
if the predicate returns false,
otherwise it returns the subject value.
The last two arguments
are an optional message and error type
that control
the message and type
of the thrown error object.
Also works with the not
, maybe
and ...of
modifiers.
Batch operations
-
check.map(things, predicates)
:
Maps each value from the things
array or object
to the corresponding predicate
and returns the array or object of results.
Passing a single predicate
instead of an array or object
maps all of the values
to the same predicate.
-
check.all(results)
:
Returns true
if all the result values are true
in an array or object
returned by map
.
-
check.any(results)
:
Returns true
if any result value is true
in an array or object
returned by map
.
Some examples
check.even(3);
check.not.even(3);
check.maybe.even(null);
check.assert.even(3);
check.assert.not.even(3);
check.assert.maybe.even(null);
check.contains('foo', 'oo')
check.contains('foe', 'oo')
check.contains(['foo', 'bar'], 'bar')
check.contains(['foo', 'bar'], 'ar')
check.like({ foo: 'bar' }, { foo: 'baz' });
check.like({ foo: 'bar' }, { baz: 'qux' });
check.array.of.nonEmptyString([ 'foo', 'bar' ]);
check.array.of.nonEmptyString([ 'foo', 'bar', '' ]);
check.array.of.inRange([ 0, 1, 2 ], 0, 2);
check.array.of.inRange([ 0, 1, 2 ], 0, 1);
check.assert(myFunction(), 'Something went wrong', CustomError);
check.map([ 'foo', 'bar', '' ], check.nonEmptyString);
check.map({
foo: 2,
bar: { baz: 'qux' }
}, {
foo: check.odd,
bar: { baz: check.nonEmptyString }
});
check.all(
check.map(
{ foo: 0, bar: '' },
{ foo: check.number, bar: check.string }
)
);
check.any(
check.map(
[ 1, 2, 3, '' ],
check.string
)
);
Are there TypeScript definitions?
Yes!
Thanks to @idchlife,
type definitions were added
to DefinitelyTyped.
You can add them to your project
via npm:
npm i @types/check-types --save-dev
Where can I use it?
As of version 2.0,
this library no longer supports ES3.
That means you can't use it
in IE 7 or 8.
Everywhere else should be fine.
If those versions of IE
are important to you,
worry not!
The 1.x versions
all support old IE
and any future 1.x versions
will adhere to that too.
See the releases
for more information.
What changed from 10.x to 11.x?
Breaking changes
were made to the API
in version 11.0.0.
Specifically,
the options
argument was removed
from the emptyString
and nonEmptyString
predicates
because it caused problematic behaviour in the assert
modifier.
Callers who were previously using options.trim
with these predicates
should call check.match
instead:
check.match(stringWithSpaces, /^\s*$/);
See the history
for more details.
What changed from 9.x to 10.x?
Breaking changes
were made to the API
in version 10.0.0.
Specifically,
the includes
predicate
was merged into the contains
predicate
and errors thrown by the assert
modifier
were given more useful error messages
including details about the failing data.
See the history
for more details.
What changed from 8.x to 9.x?
Breaking changes
were made to the API
in version 9.0.0.
Specifically,
an options
argument was added
to the emptyString
and nonEmptyString
predicates.
In each case,
if options.trim
is truthy,
strings will be trimmed
before making the comparison.
See the history
for more details.
What changed from 7.x to 8.x?
Breaking changes
were made to the API
in version 8.0.0.
Specifically,
the apply
batch operation was removed
and map
was instead changed
to work with both arrays and objects,
to simplify the API surface.
See the history
for more details.
What changed from 6.x to 7.x?
Breaking changes
were made to the API
in version 7.0.0.
Specifically,
the instance
predicate
was renamed to instanceStrict
and the builtIn
and userDefined
predicates
were combined to form
a new instance
predicate.
See the history
for more details.
What changed from 5.x to 6.x?
Breaking changes
were made to the API
in version 6.0.0.
Specifically,
the either
modifier was removed.
Instead,
calling code can use
the any
function,
or simply express the boolean logic
in JS.
See the history
for more details.
What changed from 4.x to 5.x?
Breaking changes
were made to the API
in version 5.0.0.
Specifically,
the predicates isMap
and error
were removed
in favour of the new predicate builtIn
,
which can be used to test for
all built-in objects.
See the history
for more details.
What changed from 3.x to 4.x?
Breaking changes
were made to the API
in version 4.0.0.
Specifically,
the predicate unemptyString
was renamed to nonEmptyString
and the predicate error
was changed to support
derived Error objects.
See the history
for more details.
What changed from 2.x to 3.x?
Breaking changes
were made to the API
in version 3.0.0.
Specifically,
the predicate length
was renamed to hasLength
and the predicate webUrl
was removed.
See the history
for more details.
What changed from 1.x to 2.x?
Breaking changes
were made to the API
in version 2.0.0.
Specifically:
- Support for ES3 was dropped
- The predicates
gitUrl
, email
and floatNumber
were removed. verify
was renamed to assert
.nulled
was renamed to null
.oddNumber
was renamed to odd
.evenNumber
was renamed to even
.positiveNumber
was renamed to positive
.negativeNumber
was renamed to negative
.intNumber
was renamed to integer
.bool
was renamed to boolean
.defined
was swapped to become undefined
.webUrl
was tightened to reject more cases.
See the history
for more details.
What changed from 0.x to 1.x?
Breaking changes
were made to the API
in version 1.0.0.
Specifically,
all of the predicates
were renamed
from check.isXxxx
to check.xxx
and
all of the verifiers
were renamed
from check.verifyXxxx
to check.verify.xxx
.
See the history
for more details.
How do I set up the build environment?
The build environment relies on
Node.js,
NPM,
JSHint,
Mocha,
Chai,
UglifyJS and
please-release-me.
Assuming that you already have Node.js and NPM set up,
you just need to run npm install
to
install all of the dependencies as listed in package.json
.
The unit tests are in test/check-types.js
.
You can run them with the command npm test
.
To run the tests in a web browser,
open test/check-types.html
.
What license is it released under?
MIT