Open sromexs opened 1 week ago
EDIT: cleaned up the return type signatures
export function renameKeys<
T extends Record<string | symbol, unknown>,
M extends Record<string, string>,
>(input: T, map: M): { [Key in keyof T as Key extends keyof M ? M[Key] : Key]: T[Key] } {
return Record.mapKeys(input, (key) => (key in map ? map[key as keyof M] : key)) as any;
}
export function renameKey<
T extends Record<string | symbol, unknown>,
K extends keyof T,
K2 extends string,
>(input: T, key: K, newKey: K2): { [Key in keyof T as Key extends K ? K2 : Key]: T[Key] } {
return renameKeys(input, { [key]: newKey } as Record<K, K2>) as any;
}
Hm, the types here aren't as nice as I'd like when there is a collision in renaming.
As an example:
test("name overrides", () => {
const obj = { a: 1, b: 2 } as const;
const res = renameKeys(obj, { a: "b" } as const);
expect(res).toEqual({ b: 2 }); // type is inferred as { b: 1 | 2 }
});
test("name overrides 2", () => {
const obj = { a: 1, b: 2 } as const;
const res = renameKeys(obj, { b: "a" } as const);
expect(res).toEqual({ a: 2 }); // type is inferred as { a: 1 | 2 }
});
Unfortunately, there's no way around this as the types are evaluated at compile time, but you could easily reorder the entries in the object at runtime so there's a different evaluation order in the Record.mapKeys
call and therefore get a different runtime value result.
What is the problem this feature would solve?
Currently, the
Record
module lacks a built-in, type-safe method for renaming keys in an object while preserving full type information in TypeScript. Renaming object keys is a common task in data transformation, but existing approaches often lead to loss of type information or require cumbersome and error-prone workarounds. Developers need a reliable way to rename keys without sacrificing type safety or resorting to manual type definitions.What is the feature you are proposing to solve the problem?
I propose adding two new utility functions to the
Record
module:renameKey
: A function that renames a single key in an object.renameKeys
: A function that renames multiple keys in an object based on a mapping.These functions solve the problem by:
renameKeys
allows for multiple key renames in a single operation, whilerenameKey
is optimized for single key renaming.What alternatives have you considered?
Several alternatives were considered but found lacking:
Manual Key Renaming with Type Casting:
Using Existing Utility Functions or Libraries:
Custom Helper Functions in Individual Projects:
Extending Types with Mapped Types Manually:
These alternatives either compromise on type safety, increase complexity, or don't provide a reusable and maintainable solution. By adding
renameKey
andrenameKeys
to theRecord
module, we offer a robust, type-safe, and developer-friendly solution to a common problem.