286 lines
6.7 KiB
JavaScript
286 lines
6.7 KiB
JavaScript
|
/**
|
||
|
* **This module is experimental**
|
||
|
*
|
||
|
* Experimental features are published in order to get early feedback from the community, see these tracking
|
||
|
* [issues](https://github.com/gcanti/io-ts/issues?q=label%3Av2.2+) for further discussions and enhancements.
|
||
|
*
|
||
|
* A feature tagged as _Experimental_ is in a high state of flux, you're at risk of it changing without notice.
|
||
|
*
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
import { identity } from 'fp-ts/es6/function';
|
||
|
import { pipe } from 'fp-ts/es6/pipeable';
|
||
|
import * as S from './Schemable';
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
// constructors
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
/**
|
||
|
* @category constructors
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var literal = function () {
|
||
|
var values = [];
|
||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||
|
values[_i] = arguments[_i];
|
||
|
}
|
||
|
return ({
|
||
|
is: function (u) { return values.findIndex(function (a) { return a === u; }) !== -1; }
|
||
|
});
|
||
|
};
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
// primitives
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
/**
|
||
|
* @category primitives
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var string = {
|
||
|
is: function (u) { return typeof u === 'string'; }
|
||
|
};
|
||
|
/**
|
||
|
* Note: `NaN` is excluded.
|
||
|
*
|
||
|
* @category primitives
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var number = {
|
||
|
is: function (u) { return typeof u === 'number' && !isNaN(u); }
|
||
|
};
|
||
|
/**
|
||
|
* @category primitives
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var boolean = {
|
||
|
is: function (u) { return typeof u === 'boolean'; }
|
||
|
};
|
||
|
/**
|
||
|
* @category primitives
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var UnknownArray = {
|
||
|
is: Array.isArray
|
||
|
};
|
||
|
/**
|
||
|
* @category primitives
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var UnknownRecord = {
|
||
|
is: function (u) { return u !== null && typeof u === 'object' && !Array.isArray(u); }
|
||
|
};
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
// combinators
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var refine = function (refinement) { return function (from) { return ({
|
||
|
is: function (i) { return from.is(i) && refinement(i); }
|
||
|
}); }; };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var nullable = function (or) { return ({
|
||
|
is: function (i) { return i === null || or.is(i); }
|
||
|
}); };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.15
|
||
|
*/
|
||
|
export var struct = function (properties) {
|
||
|
return pipe(UnknownRecord, refine(function (r) {
|
||
|
for (var k in properties) {
|
||
|
if (!(k in r) || !properties[k].is(r[k])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}));
|
||
|
};
|
||
|
/**
|
||
|
* Use `struct` instead.
|
||
|
*
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
* @deprecated
|
||
|
*/
|
||
|
export var type = struct;
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var partial = function (properties) {
|
||
|
return pipe(UnknownRecord, refine(function (r) {
|
||
|
for (var k in properties) {
|
||
|
var v = r[k];
|
||
|
if (v !== undefined && !properties[k].is(v)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}));
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var array = function (item) {
|
||
|
return pipe(UnknownArray, refine(function (us) { return us.every(item.is); }));
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var record = function (codomain) {
|
||
|
return pipe(UnknownRecord, refine(function (r) {
|
||
|
for (var k in r) {
|
||
|
if (!codomain.is(r[k])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}));
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var tuple = function () {
|
||
|
var components = [];
|
||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||
|
components[_i] = arguments[_i];
|
||
|
}
|
||
|
return ({
|
||
|
is: function (u) { return Array.isArray(u) && u.length === components.length && components.every(function (c, i) { return c.is(u[i]); }); }
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var intersect = function (right) { return function (left) { return ({
|
||
|
is: function (u) { return left.is(u) && right.is(u); }
|
||
|
}); }; };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var union = function () {
|
||
|
var members = [];
|
||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||
|
members[_i] = arguments[_i];
|
||
|
}
|
||
|
return ({
|
||
|
is: function (u) { return members.some(function (m) { return m.is(u); }); }
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var sum = function (tag) { return function (members) {
|
||
|
return pipe(UnknownRecord, refine(function (r) {
|
||
|
var v = r[tag];
|
||
|
if (v in members) {
|
||
|
return members[v].is(r);
|
||
|
}
|
||
|
return false;
|
||
|
}));
|
||
|
}; };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var lazy = function (f) {
|
||
|
var get = S.memoize(f);
|
||
|
return {
|
||
|
is: function (u) { return get().is(u); }
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.15
|
||
|
*/
|
||
|
export var readonly = identity;
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var alt = function (that) { return function (me) { return ({
|
||
|
is: function (i) { return me.is(i) || that().is(i); }
|
||
|
}); }; };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var zero = function () { return ({
|
||
|
is: function (_) { return false; }
|
||
|
}); };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var compose = function (to) { return function (from) { return ({
|
||
|
is: function (i) { return from.is(i) && to.is(i); }
|
||
|
}); }; };
|
||
|
/**
|
||
|
* @category combinators
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var id = function () { return ({
|
||
|
is: function (_) { return true; }
|
||
|
}); };
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
// instances
|
||
|
// -------------------------------------------------------------------------------------
|
||
|
/**
|
||
|
* @category instances
|
||
|
* @since 2.2.0
|
||
|
*/
|
||
|
export var URI = 'io-ts/Guard';
|
||
|
/**
|
||
|
* @category instances
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var Schemable = {
|
||
|
URI: URI,
|
||
|
literal: literal,
|
||
|
string: string,
|
||
|
number: number,
|
||
|
boolean: boolean,
|
||
|
nullable: nullable,
|
||
|
type: type,
|
||
|
struct: struct,
|
||
|
partial: partial,
|
||
|
record: record,
|
||
|
array: array,
|
||
|
tuple: tuple,
|
||
|
intersect: intersect,
|
||
|
sum: sum,
|
||
|
lazy: function (_, f) { return lazy(f); },
|
||
|
readonly: readonly
|
||
|
};
|
||
|
/**
|
||
|
* @category instances
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var WithUnknownContainers = {
|
||
|
UnknownArray: UnknownArray,
|
||
|
UnknownRecord: UnknownRecord
|
||
|
};
|
||
|
/**
|
||
|
* @category instances
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var WithUnion = {
|
||
|
union: union
|
||
|
};
|
||
|
/**
|
||
|
* @category instances
|
||
|
* @since 2.2.8
|
||
|
*/
|
||
|
export var WithRefine = {
|
||
|
refine: refine
|
||
|
};
|