Skip to content

Instantly share code, notes, and snippets.

@fostyfost
Created November 11, 2024 15:23
Show Gist options
  • Save fostyfost/e9985b4a126e4e7e335b3eb366311a8a to your computer and use it in GitHub Desktop.
Save fostyfost/e9985b4a126e4e7e335b3eb366311a8a to your computer and use it in GitHub Desktop.
Create Mapped Record
/* eslint-disable @typescript-eslint/consistent-type-assertions */
type ValueOf<T> = T[keyof T]
type ObjectEntries<T> = [keyof T, ValueOf<T>][]
const objectEntries = <O extends Record<string, unknown>>(object: O) => {
return Object.entries(object) as ObjectEntries<O>
}
type MappedRecord<T extends Record<string, unknown>, M extends (key: keyof T, value: T[keyof T]) => unknown> = {
[K in keyof T]: M extends (...args: unknown[]) => infer R ? R : never
}
/**
* Creates a new object by transforming each value of the input object using a mapping function.
*
* @template T - The type of the input object.
* @template M - The type of the mapping function.
*
* @param {T} record - The input object to transform.
* @param {M} mapper - A function applied to each key and value of the object.
* @returns {MappedRecord<T, M>} A new object with transformed values.
*
* @example
* const original = { field1: "Label 1", field2: "Label 2" };
*
* const mapped = createMappedRecord(original, (id, label) => ({ id, label }));
* // Result: { field1 { id: "field1", label: "Label 1" }, field2: { id: "field2", label: "Label 2" } }
*/
export function createMappedRecord<
T extends Record<string, unknown>,
M extends (key: keyof T, value: T[keyof T]) => unknown,
>(record: T, mapper: M): MappedRecord<T, M> {
const result = {} as MappedRecord<T, M>
for (const [key, value] of objectEntries(record)) {
result[key] = mapper(key, value) as M extends (...args: unknown[]) => infer R ? R : never
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment