61 lines
2.0 KiB
TypeScript
Raw Normal View History

import { arrayReduce } from 'wherehows-web/utils/array';
/**
* Aliases the exclusion / diff conditional type that specifies that an object
* contains properties from T, that are not in K
* @alias
*/
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
/**
* Aliases the selection / extract conditional type that specifies that an object
* contains properties from T, that are in K
*/
type Select<T, K> = Pick<T, Extract<keyof T, K>>;
/**
* Checks if a type is an object
* @param {any} candidate the entity to check
*/
const isObject = (candidate: any): candidate is object =>
candidate && Object.prototype.toString.call(candidate) === '[object Object]';
/**
* Checks that an object has it own enumerable props
* @param {any} object the object to the be tested
* @return {boolean} true if enumerable keys are present
*/
const hasEnumerableKeys = (object: any): boolean => isObject(object) && !!Object.keys(object).length;
2018-02-26 01:30:43 -08:00
/**
* Non mutative object attribute deletion. Removes the specified keys from a copy of the object and returns the copy.
* @template T the object type to drop keys from
* @template K the keys to be dropped from the object
* @param {T} o
* @param {Array<K extends keyof T>} droppedKeys
* @return {Pick<T, Exclude<keyof T, K extends keyof T>>}
2018-02-26 01:30:43 -08:00
*/
const omit = <T, K extends keyof T>(o: T, droppedKeys: Array<K>): Omit<T, K> => {
2018-02-26 01:30:43 -08:00
const partialResult = Object.assign({}, o);
return arrayReduce((partial: T, key: K) => {
2018-02-26 01:30:43 -08:00
delete partial[key];
return partial;
}, partialResult)(droppedKeys);
2018-02-26 01:30:43 -08:00
};
/**
* Extracts keys from a source to a new object
* @template T the object to select keys from
* @param {T} o the source object
* @param {Array<K extends keyof T>} pickedKeys
* @return {Select<T extends object, K extends keyof T>}
*/
const pick = <T extends object, K extends keyof T>(o: T, pickedKeys: Array<K>): Select<T, K> =>
arrayReduce(
(partial: T, key: K) => (pickedKeys.includes(key) ? Object.assign(partial, { [key]: o[key] }) : partial),
<T>{}
)(pickedKeys);
export { isObject, hasEnumerableKeys, omit, pick };