Skip to content

Commit

Permalink
feat: adds obj namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
OctoD committed Mar 11, 2021
1 parent d164ddf commit 6f7ada4
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/__tests__/obj.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as obj from '../obj';

const testobject = { foo: 100, bar: 200, baz: 300 };

describe(`obj`, () => {
test(`entries`, () => {
expect(expect.arrayContaining(obj.entries(testobject))).toEqual(Object.entries(testobject));
});

test(`is`, () => {
expect(obj.is(testobject)(testobject)).toBeTruthy();
expect(obj.is(1)(1)).toBeTruthy();
expect(obj.is(1)(2)).toBeFalsy();
});

test(`isExtensible`, () => {
const test = { foo: 100 }

expect(obj.isExtensible(test)).toBe(true);

Object.preventExtensions(test);

expect(obj.isExtensible(test)).toBe(false);
});

test(`isFrozen`, () => {
const test = { foo: 100 }

expect(obj.isFrozen(test)).toBe(false);

Object.freeze(test);

expect(obj.isFrozen(test)).toBe(true);
});

test(`isSealed`, () => {
const test = { foo: 100 }

expect(obj.isSealed(test)).toBe(false);

Object.seal(test);

expect(obj.isSealed(test)).toBe(true);
});

test(`keys`, () => {
expect(expect.arrayContaining(obj.keys({ foo: 1, bar: 2, baz: 3 }))).toEqual(["foo", "bar", "baz"]);
});

test(`mapkey`, () => {
const fn = obj.mapkey<typeof testobject>('baz');

expect(fn(testobject)).toBe(testobject.baz);
})

test(`pick`, () => {
expect(obj.pick(`foo`, `baz`)(testobject)).toEqual({ foo: 100, baz: 300 })
});

test(`values`, () => {
expect(expect.arrayContaining(obj.values(testobject))).toEqual([100, 200, 300])
});
});
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as filterables from "./filterables";
import * as foldables from "./foldables";
import * as mappables from "./mappables";
import * as maybe from "./maybe";
import * as obj from "./obj";
import * as option from "./option";
import * as predicate from "./predicate";
import * as result from "./result";
Expand All @@ -31,6 +32,7 @@ export {
foldables,
mappables,
maybe,
obj,
option,
predicate,
result,
Expand Down
172 changes: 172 additions & 0 deletions src/obj.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* Returns an array of key/values of the enumerable properties of an object
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* obj.entries({ foo: 10, bar: 20 }) // [["foo", 10], ["bar", 20]]
* ```
*
* @param o the object
* @returns
*/
export const entries = <T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][] => Object.entries(o);

/**
* Returns true if the object T and object U values are the same, false otherwise.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* obj.is({ lorem: "ipsum" })({ lorem: "ipsum" }) // true
* obj.is({ foo: 100 })({ bar: 200 }) // false
* ```
*
* @param t
* @returns
*/
export const is = <T>(t: T) => <U>(u: U) => Object.is(t, u);

/**
* Returns a value that indicates whether new properties can be added to an object.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* const test = { foo: 100 }
*
* obj.isExtensible(test) // true
*
* Object.preventExtensions(test);
*
* obj.isExtensible(test) // false
* ```
*
* @param o
* @returns
*/
export const isExtensible = <T>(o: T): boolean => Object.isExtensible(o);

/**
* Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* const test = { foo: 100 }
*
* obj.isFrozen(test) // false
*
* Object.freeze(test);
*
* obj.isFrozen(test) // true
* ```
*
* @param o
* @returns
*/
export const isFrozen = <T>(o: T): boolean => Object.isFrozen(o);

/**
* Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* const test = { foo: 100 }
*
* obj.isSealed(test) // false
*
* Object.seal(test);
*
* obj.isSealed(test) // true
* ```
*
* @param o
* @returns
*/
export const isSealed = <T>(o: T): boolean => Object.isSealed(o);

/**
* Returns the names of the enumerable string properties and methods of an object.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* obj.keys({ foo: 1, bar: 2, baz: 3 }) // ["foo", "bar", "baz"]
* ```
*
* @param obj
* @returns
*/
export const keys = <T>(obj: T): Array<keyof T> => Object.keys(obj) as Array<keyof T>;

/**
* Creates a mapper function for the type T.
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* const test = { foo: 200, bar: 'baz' };
*
* const map = obj.mapkey<typeof test>('foo')
*
* map(test) // 200
*
* ```
*
* @param key
* @returns
*/
export const mapkey = <T>(key: keyof T): (arg: T) => T[typeof key] => (arg: T) => arg[key]

/**
* Given a set of properties T whose keys are in the object U, returns a new object with all picked properties
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* const test = { foo: 100, bar: 200, baz: 300 };
*
* obj.pick(`foo`, `baz`)(test) // { foo: 100, baz: 300 }
* ```
*
* @param keys
* @returns
*/
export const pick = <T extends string>(... keys: T[]): (<U extends Record<T, any>>(o: U) => Pick<U, T>) => o => keys.reduce(
(obj, key) => ({... obj, [key]: o[key] }),
{} as Pick<any, T>
);

/**
* Returns an array of values of the enumerable properties of an object
* @since 2.10.0
* @example
*
* ```ts
* import { obj } from 'tiinvo';
*
* obj.values({ foo: 1, bar: 2, baz: 3 }) // [1, 2, 3]
* ```
*
* @param obj
* @returns
*/
export const values = <T>(obj: { [s: string]: T }): T[] => Object.values(obj);

0 comments on commit 6f7ada4

Please sign in to comment.