UNPKG

@typed/fp

Version:

Data Structures and Resources for fp-ts

252 lines 5.22 kB
/** * Guard is a Typeclass for expressing Refinements * * @since 0.9.5 */ import { identity, pipe } from 'fp-ts/function'; import { memoize } from './Schemable'; // ------------------------------------------------------------------------------------- // constructors // ------------------------------------------------------------------------------------- /** * @category constructors * @since 0.9.5 */ export const literal = (...values) => ({ is: (u) => values.findIndex((a) => a === u) !== -1, }); // ------------------------------------------------------------------------------------- // Decoder // ------------------------------------------------------------------------------------- /** * @category Decoder * @since 0.9.5 */ export const string = { is: (u) => typeof u === 'string', }; /** * Note: `NaN` is excluded. * * @category Decoder * @since 0.9.5 */ export const number = { is: (u) => typeof u === 'number' && !isNaN(u), }; /** * @category Decoder * @since 0.9.5 */ export const boolean = { is: (u) => typeof u === 'boolean', }; /** * @category Decoder * @since 0.9.5 */ export const date = { is: (u) => u instanceof Date, }; /** * @category Decoder * @since 0.9.5 */ export const unknownArray = { is: Array.isArray, }; /** * @category Decoder * @since 0.9.5 */ export const unknownRecord = { is: (u) => u !== null && typeof u === 'object' && !Array.isArray(u), }; // ------------------------------------------------------------------------------------- // Combinator // ------------------------------------------------------------------------------------- /** * @category Combinator * @since 0.9.5 */ export const refine = (refinement) => (from) => ({ is: (i) => from.is(i) && refinement(i), }); /** * @category Combinator * @since 0.9.5 */ export const nullable = (or) => ({ is: (i) => i === null || or.is(i), }); /** * @category Combinator * @since 2.2.15 */ export const struct = (properties) => pipe(unknownRecord, refine((r) => { for (const k in properties) { if (!(k in r) || !properties[k].is(r[k])) { return false; } } return true; })); /** * Use `struct` instead. * * @category Combinator * @since 0.9.5 * @deprecated */ export const type = struct; /** * @category Combinator * @since 0.9.5 */ export const partial = (properties) => pipe(unknownRecord, refine((r) => { for (const k in properties) { const v = r[k]; if (v !== undefined && !properties[k].is(v)) { return false; } } return true; })); /** * @category Combinator * @since 0.9.5 */ export const array = (item) => pipe(unknownArray, refine((us) => us.every(item.is))); /** * @category Combinator * @since 0.9.5 */ export const record = (codomain) => pipe(unknownRecord, refine((r) => { for (const k in r) { if (!codomain.is(r[k])) { return false; } } return true; })); /** * @category Combinator * @since 0.9.5 */ export const tuple = (...components) => ({ is: (u) => Array.isArray(u) && u.length === components.length && components.every((c, i) => c.is(u[i])), }); /** * @category Combinator * @since 0.9.5 */ export const intersect = (right) => (left) => ({ is: (u) => left.is(u) && right.is(u), }); /** * @category Combinator * @since 0.9.5 */ export const union = (second) => (first) => ({ is: (u) => first.is(u) || second.is(u), }); /** * @category Combinator * @since 0.9.5 */ export const sum = (tag) => (members) => pipe(unknownRecord, refine((r) => { const v = r[tag]; if (v in members) { return members[v].is(r); } return false; })); /** * @category Combinator * @since 0.9.5 */ export const lazy = (f) => { const get = memoize(f); return { is: (u) => get().is(u), }; }; /** * @category Combinator * @since 2.2.15 */ export const readonly = identity; /** * @category Combinator * @since 0.9.5 */ export const alt = (that) => (me) => ({ is: (i) => me.is(i) || that().is(i), }); /** * @category Combinator * @since 0.9.5 */ export const zero = () => ({ is: (_) => false, }); /** * @category Combinator * @since 0.9.5 */ export const compose = (to) => (from) => ({ is: (i) => from.is(i) && to.is(i), }); /** * @category Combinator * @since 0.9.5 */ export const id = () => ({ is: (_) => true, }); // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- /** * @category instances * @since 0.9.5 */ export const URI = '@typed/fp/Guard'; /** * @category instances * @since 0.9.5 */ export const Schemable = { URI, literal, string, number, boolean, date, nullable, struct, record, array, tuple: tuple, intersect, sum, lazy: (_, f) => lazy(f), branded: identity, unknownArray, unknownRecord, }; /** * @category instances * @since 0.9.5 */ export const WithUnion = { union, }; /** * @category instances * @since 0.9.5 */ export const WithRefine = { refine: refine, }; //# sourceMappingURL=Guard.js.map