A Quick Guide to Typing.js
1. Overview
Typing.js is an expressive and intuitive type checking and JSON schema validation library for Node.js. It goes beyond the JSON schema validation, it actually looks like a runtime type system for JavaScript.
Features:
- a set of commonly used built-in types, i.e. int, str, array, tuple, table;
- C++ template style type definition;
- structure based pattern matching
- recursive type
Samples:
// import module and the built-in typesvar typing = require('typing');var int = typing.int;var str = typing.str;...var tuple = typing.tuple;var table = typing.table; // primitive type checkingtyping(bool, true) //truetyping(int(0,10), 5) //truetyping(char, 'q') //truetyping(str(3,10), 'hello') //truetyping(enumeration('foo', 'bar'), 'foo') //true // composite type checkingtyping( tuple(int, str, tuple(str, str)), [23, 'todd', ['82301588', 'todd@mail.com']]) //true // pattern matchingtyping( { id : int, male : bool, name : str(1,50), contact : { tel : str, email : str } }, { id : 23, male : true, name : 'todd', contact : { tel : '82301588', email : 'todd@mail.com' } }) //true
Usage:
typing(type, data); //true: matched; false: not matched
where type
can be:
- Function with
__name__
and__check__
property.
For example, the built-in type bool
is defined as:
function bool() {}bool.__name__ = 'bool';bool.__check__ = function(value) { return true === value || false === value; }
typing(type, data)
will call type.__check__(data)
in this case. You can define your own types this way, however, be aware that typing comes with a set of built-in types, which can be used to construct complex types.
- JSON object.
For example,
{ status : { code : int, message : str }, data : table(int, str, tuple(str, str))}
typing(type, data)
will perform pattern matching between type and data based on the structure and recursively check the type of each property.
- String.
For example,
// define 3x3 matrix type under the name 'matrix_3x2'typing.define('matrix_3x2', tuple(tuple(int, int), tuple(int, int), tuple(int, int))); // check type with the type nametyping('matrix_3x2', [[11, 12], [21, 22], [31, 32]]); //true
2. How to define types?
2.1. Define custom type with the built-in types
// int(1): integer >= 1;// str(1,50): string with length between 1 to 50;// tuple: array with specified type and number of elementsvar t_employee = tuple(int(1), str(1,50), tuple(str,str)); typing(t_employee, [123, 'todd', ['1355-0011-107', 'CD 5607']]); //true typing(t_employee, [0, 'todd', ['1355-0011-107', 'CD 5607']]); //false
2.2. Define custom type in JSON
// typing will do pattern matching based the type defined in JSON// nullable : null or the wrapped type// table: equivalent of array(tuple)var t_response = { status : { code : int, message : str }, data : nullable(table(int(1), str(1,50), tuple(str,str)))}; typing(t_response, { status : { code : 200, message : 'OK' }, data : [ [1, 'Todd', ['1355-0011-107', 'CA 5607']], [2, 'April', ['1582-0011-108', 'CA 5607']], [3, 'Rex', ['1522-1011-138', 'CA 1008']] ]}); //true typing(t_response, { status : { code : 404, message : 'NOT FOUND' }}); //true typing(t_response, { status : { code : 300 }}); //false, status.message is missing
2.3. Define recursive type
// define a recursive binary tree type under the name 'tree'// nullalbe(type): extend the wrapped type to accept null value// type(name): refers to a lazy resolved typetyping.define('tree', { value : int, left : nullable(type('tree')), right : nullable(type('tree'))}); typing('tree', { value : 1, left : { value : 2, left : { value : 3 } }, right : { value : 4, right : { value : 5 } }}); //true
3. Built-in Types##
1. any
any
matches any value in JavaScript including null and undefined.
typing(any, null); //truetyping(any, undefined); //truetyping(any, 123); //truetyping(any, 'hello typing.js'); //truetyping(any, {}); //truetyping(any, []); //truetyping(any, function(){}); //true
2. bool
bool
matches true
or false
.
typing(bool, true); //truetyping(bool, false); //true
3. int
int
matches integers. You can specify the minimal and maximal value by int(min)
or int(min,max)
.
typing(int, -103); //true, no min and maxtyping(int, 'hello'); //falsetyping(int(100), 99); //false, matches integer >= 100typing(int(0,1000), 1000); //true, matches integer >= 0 and <= 1000
4. num
num
matches numbers. You can specify the minimal and maximal value by num(min)
or num(min,max)
.
typing(num, -10.3); //true, no min and maxtyping(num, 'hello'); //falsetyping(num(100), 99.9); //false, matches num >= 100typing(num(0,51), 25.9); //true, matches num >= 0 and <= 51
5. str
str
matches strings. You can specify the minimal and maximal lenght by str(min)
or str(min,max)
.
typing(str, null); //truetyping(str, ''); //truetyping(str(0), null); //truetyping(str(0), ''); //truetyping(str(3), 'foo'); //true, matches string with length >= 3typing(str(4), 'foo'); //falsetyping(str(1,3), ''); //false, matches string with length >= 1 and <= 3 typing(str(1,3), 'hello'); //false, matches string with length >= 1 and <= 3
6. enumeration
enumeration
matches one of the values.
typing(enumeration('Saturday', 'Sunday'), 'Sunday'); //truetyping(enumeration('Saturday', 'Sunday'), 'Friday'); //falsetyping(enumeration(1, 2, 3), 2); //truetyping(enumeration(1, 2, 3), 5); //false
7. array
array
matches array objects. You can specify the element type of the array.
typing(array, []); //truetyping(array, [1, 'foo', {}, null]); //truetyping(array(str(3,3)), ['foo', 'bar', 'pee', 'ijk']); //truetyping(array(array(str(3,3))), [['foo'], ['bar', 'pee', 'ijk']]); //truetyping(array({id : int, name : str}), [{id : 1, name : 'todd'}]); //truetyping(array, null); //falsetyping(array(str(3,3)), ['fooo', 'barr', 'pee', 'ijk']); //falsetyping(array(str(3,3)), [1, 'bar', 'pee', 'ijk']); //false
8. tuple
tuple
matches array objects with specified number and type of elements.
typing(tuple(int, str), [123, 'todd']); //truetyping(tuple(int(1,100), str(1,100), tuple(str(11, 11), str(1))), [100, 'foobar', ['13550013607', 'Tianfu Software Park C2']]); //truetyping(tuple(int(1,100), str(1,100), {phone : str, address : str}), [23, 'todd', {phone : '13550013607', address : 'CD 5037'}]); //truetyping(tuple(str), null); //false
9. table
table(type1, type2 ...)
is equivalent to array(tuple(type1, type2 ...)
, which matches tabular data.
typing(table(int(1,100), str(1,1), str), [[1, 'h', 'host'], [2, 'p', null]]); //truetyping(table(int(1,100), str(1,1), str), null); //falsetyping(table(int(1,100), str(1,1), str), [[1, 'h', 'host'], [2, 'port', null]]); //false