Last active
November 29, 2021 19:06
-
-
Save crutchcorn/54dba53ae282f3ac0c11cc40051b9c2a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @callback objectMapCallback | |
* @param value - The value of the key that is currently being modified. Added as an attempt to duplicate Array.map `value` | |
* @param {string} key - The key that is currently being modified. Added as an attempt to duplicate Array.map `index` | |
* @param object - The original untouched object that the map function is being called on. Added as an attempt to duplicate Array.map `array` | |
*/ | |
/** | |
* Map through all keys in an object and call a CB. Assign that CB's return value to the key in question | |
* @param object - The object to make this call on. This would otherwise be bound to `Object.prototype` but I don't like breaking the web | |
* @param {objectMapCallback} cb - The callback in order to run the `Object.map` function | |
* @returns - The object with it's keys altered by the cb param | |
*/ | |
export function ObjectMap<T extends Record<string, any>>(object: T, cb: (value: T[string], key: keyof T, object?: T) => any): { | |
[key in keyof T]: any | |
} { | |
return Object.keys(object).reduce((prev, key) => { | |
prev[key] = cb(object[key], (key as any), object); | |
return prev; | |
}, ({} as any)); | |
} | |
/** | |
* @callback objectFilterCallback | |
* @param value - The value of the key that is currently being checked against. Added as an attempt to duplicate Array.filter `value` | |
* @param {string} key - The key that is currently being used to check. Added as an attempt to duplicate Array.filter `index` | |
* @param object - The original untouched object that the filter function is being called on. Added as an attempt to duplicate Array.filter `array` | |
*/ | |
/** | |
* Map through all keys in an object and call a CB. Decide to keep the Object key in the return object based on the truthyness of the CB's return value | |
* @param object - The object to make this call on | |
* @param {objectFilterCallback} cb - The callback in order to run the `Object.map` function | |
* @returns - The object with it's keys altered by the cb param | |
*/ | |
export function ObjectFilter<T extends Record<string, any>>(object: T, cb: (value: T[string], key: keyof T, object?: T) => any): Partial<T> { | |
return Object.keys(object).reduce((prev, key) => { | |
const toKeep = cb(object[key], (key as any), object); | |
if (toKeep) { | |
prev[key] = object[key]; | |
} | |
return prev; | |
}, ({} as any)); | |
} | |
// NaN also, but `typeof NaN` === number | |
type Falsy = false | null | undefined | 0 | -0 | 0n | ""; | |
/** | |
* Remove any keys where the value is falsy | |
*/ | |
/** | |
* Remove any keys where the value is falsy | |
*/ | |
export function RemoveFalsyObjectKeys<T extends Record<string, any>>(obj: T): { | |
[K in keyof T as Exclude<T[K], Falsy> extends never ? never : K]: Exclude<T[K], Falsy>; | |
} { | |
return Object.keys(obj).reduce((prev, key) => { | |
if (obj[key]) { | |
prev[key] = obj[key]; | |
} | |
return prev; | |
}, {} as any); | |
} | |
/** | |
* Immutably set object property | |
*/ | |
export function ObjectImmutablySetProp<T extends object, K extends keyof T, V>(object: T, key: K, val: V): { | |
[P in keyof T]: P extends K ? V : T[P]; | |
} { | |
return Object.assign({}, object, {[key]: val}) as any; | |
} | |
/** | |
* Util type to only keep the keys from an array of an object | |
* @param obj - The object to make this call on | |
* @param keyArr - A string array of the keys to keep | |
* @constructor | |
*/ | |
export function ObjectPick<Obj extends Record<string, any>, Keys extends Array<keyof Obj>>(obj: Obj, keyArr: Keys): { | |
[key in keyof Obj as Exclude<Keys[number], key>]: Obj[key]; | |
} { | |
return Object.entries(obj).reduce((prev, [key, val]) => { | |
if (!keyArr.includes(key)) return prev; | |
// prev[key] = val; | |
return prev; | |
}, {} as any) | |
} | |
// -------------------------------------------------------------------------------------------------- | |
type DeepReplaceKeysObj<Obj extends object, T> = { | |
[key in keyof Obj]: | |
Obj[key] extends Array<infer Q> ? | |
Array<DeepReplaceKeys<Q, T>> : | |
Obj[key] extends object ? | |
DeepReplaceKeys<Obj[key], T> : | |
T; | |
}; | |
type DeepReplaceKeys<Obj, T> = Obj extends object ? DeepReplaceKeysObj<Obj, T> : Obj; | |
type B = DeepReplaceKeys<{test: {deep: false}}, true>; | |
// true | |
type A = B['test']['deep'] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment