Map over object
/**
* Creates a new object with the same keys as the given object,
* and values generated by running each own enumerable string keyed property of the object thru the function.
*
* @param {Object.<string, ObjectValue>} object - The object to iterate over.
* @param {(value: ObjectValue) => Returned} fn - The function invoked per iteration.
* @returns {Object.<string, Returned>} The new object with the same keys and mapped values.
*
* @template ObjectValue The type of the values in the input object.
* @template Returned The type of the values in the returned object.
*
* @example
* const object = { a: 1, b: 2 };
* const fn = (value) => value * 2;
* const result = mapObject(object, fn); // { a: 2, b: 4 }
*/
export const mapObject = <
ObjectValue,
Returned,
Result extends Record<string, Returned>,
>(
object: { [key: string]: ObjectValue },
fn: (value: ObjectValue) => Returned,
): Result =>
Object.fromEntries(
Object.entries(object).map(([key, value]) => [key, fn(value)]),
) as Result