effect icon indicating copy to clipboard operation
effect copied to clipboard

Add renameKey and renameKeys functions to the Record module

Open sromexs opened this issue 5 months ago • 2 comments

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:

  1. renameKey: A function that renames a single key in an object.

    • Signature:
      function renameKey<
        T extends Record<string | symbol, unknown>,
        K extends keyof T,
        K2 extends string,
      >(input: T, key: K, newKey: K2): { [P in Exclude<keyof T, K> | K2]: T[P extends K2 ? K : P] };
      
    • Usage:
      const source = { foo: 1, bar: "baz" } as const;
      const result = renameKey(source, "foo", "yolo");
      // Resulting type:
      // { readonly yolo: 1; readonly bar: "baz"; }
      
  2. renameKeys: A function that renames multiple keys in an object based on a mapping.

    • Signature:
      function renameKeys<
        T extends Record<string | symbol, unknown>,
        M extends Record<string, string>,
      >(input: T, map: M): {
        [Property in keyof T as Property extends keyof M ? M[Property] : Property]: T[Property];
      };
      
    • Usage:
      const source = { foo: 1, bar: "baz" } as const;
      const mapping = { foo: "yolo", bar: "qux" } as const;
      const result = renameKeys(source, mapping);
      // Resulting type:
      // { readonly yolo: 1; readonly qux: "baz"; }
      

These functions solve the problem by:

  • Preserving Type Safety: They maintain full type information of the original object, ensuring that the returned object accurately reflects the types.
  • Convenience: Provide straightforward methods to rename one or multiple keys without manual type definitions.
  • Flexibility: renameKeys allows for multiple key renames in a single operation, while renameKey is optimized for single key renaming.

What alternatives have you considered?

Several alternatives were considered but found lacking:

  1. Manual Key Renaming with Type Casting:

    • Drawbacks:
      • Verbose and error-prone.
      • Requires manual updates to types, increasing maintenance overhead.
      • Risk of losing type information or introducing type errors.
  2. Using Existing Utility Functions or Libraries:

    • Drawbacks:
      • Third-party libraries may not handle type preservation adequately.
      • Introduces additional dependencies to the project.
      • May not align with the project's existing patterns or standards.
  3. Custom Helper Functions in Individual Projects:

    • Drawbacks:
      • Leads to code duplication across different projects.
      • Inconsistent implementations can cause confusion and bugs.
      • Lacks the optimization and testing that a standardized utility would have.
  4. Extending Types with Mapped Types Manually:

    • Drawbacks:
      • Can become complex quickly, especially with deeply nested objects.
      • Increases cognitive load for developers.
      • Not practical for dynamic key renaming based on runtime data.

These alternatives either compromise on type safety, increase complexity, or don't provide a reusable and maintainable solution. By adding renameKey and renameKeys to the Record module, we offer a robust, type-safe, and developer-friendly solution to a common problem.

sromexs avatar Sep 22 '24 01:09 sromexs