UNPKG

typing

Version:

A type checking and JSON schema validation library

294 lines (227 loc) 7.58 kB
#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:** 1. a set of commonly used built-in types, i.e. int, str, array, tuple, table; 2. C++ template style type definition; 3. structure based pattern matching 4. recursive type **Samples:** ```JavaScript // import module and the built-in types var typing = require('typing'); var int = typing.int; var str = typing.str; ... var tuple = typing.tuple; var table = typing.table; // primitive type checking typing(bool, true) //true typing(int(0,10), 5) //true typing(char, 'q') //true typing(str(3,10), 'hello') //true typing(enumeration('foo', 'bar'), 'foo') //true // composite type checking typing( tuple(int, str, tuple(str, str)), [23, 'todd', ['82301588', 'todd@mail.com']] ) //true // pattern matching typing( { 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:** ```Javascript typing(type, data); //true: matched; false: not matched ``` where ```type``` can be: 1) Function with ```__name__``` and ```__check__``` property. For example, the built-in type ```bool``` is defined as: ```Javascript 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. 2) JSON object. For example, ```Javascript { 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. 3) String. For example, ```Javascript // 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 name typing('matrix_3x2', [[11, 12], [21, 22], [31, 32]]); //true ``` ##2. How to define types? **2.1. Define custom type with the built-in types** ```JavaScript // int(1): integer >= 1; // str(1,50): string with length between 1 to 50; // tuple: array with specified type and number of elements var 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** ```JavaScript // 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** ```Javascript // 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 type typing.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. ```Javascript typing(any, null); //true typing(any, undefined); //true typing(any, 123); //true typing(any, 'hello typing.js'); //true typing(any, {}); //true typing(any, []); //true typing(any, function(){}); //true ``` **2. bool** ```bool``` matches ```true``` or ```false```. ```JavaScript typing(bool, true); //true typing(bool, false); //true ``` **3. int** ```int``` matches integers. You can specify the minimal and maximal value by ```int(min)``` or ```int(min,max)```. ```JavaScript typing(int, -103); //true, no min and max typing(int, 'hello'); //false typing(int(100), 99); //false, matches integer >= 100 typing(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)```. ```JavaScript typing(num, -10.3); //true, no min and max typing(num, 'hello'); //false typing(num(100), 99.9); //false, matches num >= 100 typing(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)```. ```JavaScript typing(str, null); //true typing(str, ''); //true typing(str(0), null); //true typing(str(0), ''); //true typing(str(3), 'foo'); //true, matches string with length >= 3 typing(str(4), 'foo'); //false typing(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. ```JavaScript typing(enumeration('Saturday', 'Sunday'), 'Sunday'); //true typing(enumeration('Saturday', 'Sunday'), 'Friday'); //false typing(enumeration(1, 2, 3), 2); //true typing(enumeration(1, 2, 3), 5); //false ``` **7. array** ```array``` matches array objects. You can specify the element type of the array. ```JavaScript typing(array, []); //true typing(array, [1, 'foo', {}, null]); //true typing(array(str(3,3)), ['foo', 'bar', 'pee', 'ijk']); //true typing(array(array(str(3,3))), [['foo'], ['bar', 'pee', 'ijk']]); //true typing(array({id : int, name : str}), [{id : 1, name : 'todd'}]); //true typing(array, null); //false typing(array(str(3,3)), ['fooo', 'barr', 'pee', 'ijk']); //false typing(array(str(3,3)), [1, 'bar', 'pee', 'ijk']); //false ``` **8. tuple** ```tuple``` matches array objects with specified number and type of elements. ```JavaScript typing(tuple(int, str), [123, 'todd']); //true typing(tuple(int(1,100), str(1,100), tuple(str(11, 11), str(1))), [100, 'foobar', ['13550013607', 'Tianfu Software Park C2']]); //true typing(tuple(int(1,100), str(1,100), {phone : str, address : str}), [23, 'todd', {phone : '13550013607', address : 'CD 5037'}]); //true typing(tuple(str), null); //false ``` **9. table** ```table(type1, type2 ...)``` is equivalent to ```array(tuple(type1, type2 ...)```, which matches tabular data. ```JavaScript typing(table(int(1,100), str(1,1), str), [[1, 'h', 'host'], [2, 'p', null]]); //true typing(table(int(1,100), str(1,1), str), null); //false typing(table(int(1,100), str(1,1), str), [[1, 'h', 'host'], [2, 'port', null]]); //false ```