/** * **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 };