UNPKG

tiinvo

Version:

A library of types and utilities for your TypeScript and JavaScript projects

327 lines (326 loc) 7.17 kB
//#region guards /** * Returns true if `x` is of type `object` and not null * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.guard({}); // true * Obj.guard(null); // false * ``` * * @param x the object * @returns * - true if x is object and not null * - false otherwise * @group Guardables * @since 4.0.0 */ export const guard = (x) => typeof (x) === 'object' && !!x; /** * Returns a guard which checks if a value `v` implements a shape `s` * * @example * ```ts * import { Obj, Str, Num, Bool } from 'tiinvo'; * * const isABC = Obj.guardOf({ * a: Str.guard, * b: Num.guard, * c: Bool.guard * }); * * isABC({ a: `foo`, b: 1, c: true }); // true * isABC({ a: `foo`, b: false, c: 1 }); // false * * // you can also set recursive shapes, or directly more comples ones * * const isUser = Obj.guardOf({ * name: Str.guard, * surname: Str.guard, * age: Num.guard, * billing: { * address: Str.guard, * city: Str.guard, * } * }) * * isUser(10) // false * isUser({}) // false * isUser({ * name: 'john', * surname: 'doe', * age: 44, * }) // false * isUser({ * name: 'john', * surname: 'doe', * age: 44, * billing: { * * } * }) // false * isUser({ * name: 'john', * surname: 'doe', * age: 44, * billing: { * address: '', * } * }) // false * isUser({ * name: 'john', * surname: 'doe', * age: 44, * billing: { * address: 'some address', * city: 'some city', * } * }) // true * ``` * * @template A the guard structure * @param s the struct which represents the guarded type * @returns the `Guardable<A>` if s is an `object`, otherwise it throws a `TypeError` * @group Guardables * @since 4.0.0 */ export const guardOf = (s) => { if (!guard(s)) { throw new TypeError("Invalid Struct guard, expected an object (GuardsFromStruct<a>), got " + typeof s); } return (v) => { if (!guard(v)) { return false; } const keys = Object.keys(s); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const currentvalue = v[key]; const currentguard = s[key]; const case1 = guard(currentguard) && guardOf(currentguard)(currentvalue); const case2 = typeof currentguard === 'function' && currentguard(currentvalue); if (!case1 && !case2) { return false; } } return true; }; }; export function hasKey(k, o) { if (arguments.length === 2) { return guard(o) && o.hasOwnProperty(k); } return (b) => guard(b) && b.hasOwnProperty(k); } ; export function hasKeyOf(k, g, o) { const og = (k, g, o) => guard(o) && o.hasOwnProperty(k) && g(o[k]); if (!!k && !!g && !!o) { return og(k, g, o); } return (o) => og(k, g, o); } //#endregion //#region native methods /** * Copy the values of all of the enumerable own properties from one or more source objects to a new object. * * **important**: This will not mutate any object, it will always return a new one instead. * * @example * * ```ts * import { Obj } from 'tiinvo'; * * const a = { a: 1, b: 2 }; * const b = { b: 3, c: 4 }; * const c = { c: 5, d: 6 }; * * Obj.assign(a, b, c); * // { a: 1, b: 3, c: 5, d: 6 } * ``` * * @returns The target object * @group Natives * @since 4.0.0 */ export const assign = (x, ...b) => Object.assign({}, x, ...b); /** * Returns an array of key/values of the enumerable properties of an object `o` * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.entries({ a: 1, b: 2 }); // [ ['a', 1], ['b', 2] ] * ``` * * @template O the object's type * @param o the object * @returns the entries * @group Natives * @since 4.0.0 */ export const entries = Object.entries; /** * Prevents the modification of existing property attributes and values, * and prevents the addition of new properties. * * @example * * ```ts * import { Obj } from 'tiinvo'; * * const a = { a: 1, b: 2 }; * Obj.freeze(a); * a.a = 100; // throws * ``` * * @group Natives * @since 4.0.0 */ export const freeze = Object.freeze; /** * Returns an object created by key-value entries for properties and methods * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.fromEntries([ ['a', 1], ['b', 2] ]) // { a: 1, b: 2 } * ``` * * @param entries the entries * @returns * @group Natives * @since 4.0.0 */ export const fromEntries = Object.fromEntries; /** * Gets a property `a` from an object `b` and returns a `Option.t<c>` * * @example * * ```ts * import { Obj } from 'tiinvo'; * * const get = Obj.get(`foo`); * * get({ foo: `bar` }); // some<`bar`> * get({}); // none * ``` * * @param a the property to get * @returns * @group Natives * @since 4.0.0 */ export const get = (a) => (b) => hasKey(a)(b) ? b[a] : null; export function omit(k, o) { const fn = (x, y) => { const omitted = {}; const ownedkeys = keys(y); for (let index = 0; index < ownedkeys.length; index++) { const key = ownedkeys[index]; if (!x.includes(key)) { omitted[key] = y[key]; } } return omitted; }; if (Array.isArray(k) && !!o) { return fn(k, o); } return (b) => fn(k, b); } ; export function pick(keys, o) { const fn = (x, y) => { const o = {}; for (let i = 0; i < x.length; i++) { const key = x[i]; if (hasKey(key)(y)) { o[key] = y[key]; } } return o; }; if (Array.isArray(keys) && !!o) { return fn(keys, o); } return (b) => fn(keys, b); } //#endregion //#region mappables /** * Maps an object `a` to a value `b` * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.map(Object.keys)({ a: 10, b: 20 }); // ['a', 'b'] * Obj.map((x: Record<string, number>) => x.a ?? 0)({ a: 10 }); // 10 * Obj.map((x: Record<string, number>) => x.a ?? 0)({ b: 10 }); // 0 * ``` * * @param a * @returns * @since 4.0.0 **/ export const map = (m) => (a) => guard(a) ? m(a) : null; /** * Returns the names of the enumerable string properties and methods of an object. * * @example * ```ts * import { Obj } from 'tiinvo'; * * Obj.keys({ a: 10, b: 20 }) // ['a', 'b'] * ``` * * @since 4.0.0 */ export const keys = Object.keys; /** * Returns an object size * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.size({ a: 1, b: 2 }) // 2 * Obj.size({}) // 0 * ``` * * @param x the object * @returns the size (count of keys) of the object * @since 4.0.0 **/ export const size = (x) => keys(x).length; /** * Returns an array of values of the enumerable properties of an object * * @example * * ```ts * import { Obj } from 'tiinvo'; * * Obj.values({ a: 1, b: 2 }) // [1, 2] * Obj.values({}) // [] * ``` * * @param a * @returns * @since 4.0.0 **/ export const values = Object.values; ; //#endregion