Declaration of types for invoking the lodash `mapKeys` function

Is there a way to create a function that can map object keys from camelCase to snakeCase, and be used multiple times with different objects?

I have already written a function called mapKeysToSnakeCase which does the job, but I'm curious if there is a better way using generic types instead of just relying on any.

Any suggestions on how this can be achieved?

export function mapKeysToSnakeCase(data: any): any {
    return mapKeys(data, (value, key) => snakeCase(key));
}

Before:

const camelCase = {
    firstName: 'John',
    lastName: 'Smith',
};

After:

const snakeCase = {
    first_name: 'John',
    last_name: 'Smith',
};

@edit

I previously attempted a new type definition as suggested in the first answer, but encountered warnings in usage context. This is why I am exploring options using generic types.

sync getData(): Promise<X> {
    (...)
    return mapKeysToSnakeCase(camelCaseX);
}

error:

TS2741: Property 'first_name' is missing in type 'KV' but required in type 'X'.

Answer №1

Seeking assistance from my colleague, we collaborated on finding the most optimal solution:

function convertKeysToSnakeCase<T>(data: Record<string, any>): T {
    return convertKeys(data, (value, key) => snake_case(key)) as T;
}

This method aligns well with scenarios such as:

getData(): Promise<Y> {
    (...)
    return convertKeysToSnakeCase<Y>(camelCaseY);
}

Answer №2

To establish a key-value type structure, you can proceed as shown:

type KeyValue = { [x: string]: string }; // x represents a string type for the key and value is also of string type

This structure can be utilized in the following manner:

export function convertKeysToSnakeCase(data: KeyValue): KeyValue {
  return convertKeys(data, (value, key) => snakeCase(key));
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to make a node application run as an executable within an NX workspace

The structure of an NX workspace really caught my attention, which led me to start using it for a new CLI project I was working on. I began by setting up a @nrwl/node:application, but I'm currently facing some issues trying to make it executable. I ...

Is Angular 9's default support for optional chaining in Internet Explorer possible without the need for polyfill (core-js) modifications with Typescript 3.8.3?

We are in the process of upgrading our system to angular 9.1.1, which now includes Typescript 3.8.3. The @angular-devkit/[email protected] utilizing [email protected]. We are interested in implementing the optional chaining feature in Typescript ...

How to extract Response body as either plain text or XML in an AngularJS 2 HTTP GET call

I have a challenge with making a get request to the server that returns XML: let responseText = ""; this.http.get('http://example.com', {headers : headers}) .map((res:Response) => res.text()).subscribe(data => responseText = data); H ...

When canActivate returns false, the screen in Angular 2 will still be accessed

I am encountering a problem where my canActivate method is returning false, but still navigating to the blocked screen. This issue seems to only occur in Chrome, as everything works fine in IE. Here is how the canActivate method looks: canActivate(route: ...

Angular 6 is experiencing an issue with the functionality of the file toggle JS

Currently, I am utilizing the file toggle.js within the Urban theme. In the HTML chatbox, using the img, the file toggle.js is hardcoded and is functioning properly. However, when implementing code in Angular 6, the toggle.js is not functioning as expecte ...

Is Angular UI's data binding more of a push or pull mechanism? How can I optimize its speed?

Suppose I have a variable a that is displayed in HTML as {{a}}. If I then update its value in TypeScript using a = "new value";, how quickly will the new value be reflected in the user interface? Is there a mechanism that periodically checks all bound var ...

Guide on specifying a type for a default export in a Node.js module

export const exampleFunc: Function = (): boolean => true; In the code snippet above, exampleFunc is of type Function. If I wish to define a default export as shown below, how can I specify it as a Function? export default (): boolean => true; ...

I am encountering issues with the TypeScript repository build on my local machine, but it successfully passes when

I am encountering an issue with a TypeScript repository failing to build on my local machine. The error message I receive is as follows: $ tsc --pretty -p tsconfig.json ../../../../../../node_modules/@types/graphql/subscription/subscribe.d.ts:17:12 - erro ...

Infinite rendering caused by React custom hook

I developed a custom hook that retrieves data from a News API and provides handling for loading, errors, and data (similar to Apollo Client). The issue I'm facing is that the hook seems to trigger infinitely, even when the items in the dependency arra ...

Tips for simulating the getCustomRepository function in typeORM

I am facing a challenge in unit-testing a class that has a getCustomRepository method in its constructor. I'm struggling to find an easy way to mock it. Below is the code for my class: import {getCustomRepository} from 'typeorm'; export cl ...

Update the mandatory fields in the required interface to extend to another interface, while ensuring that all subfields become

Currently, I have defined 2 interfaces: interface BattleSkills { strength: number; armor: number; magic_resistance: number; health: number; mana: number; intelligence: number; accuracy: number; agility: number; critical_damage: number; } ...

Cannot assign an array of Typescript type Never[] to an array of objects

Creating an object array can sometimes lead to errors, let's take a look at an example: objectExample[a].push({ id: john, detail: true }); objectExample[a].push({ id: james, detail: false}); const objectExample = { a = [ { id: john, detail: true} ...

Transferring a JSON file between components within Angular 6 utilizing a service

I have been facing an issue in passing the response obtained from http.get() in the displayresults component to the articleinfo component. Initially, I used queryParams for this purpose but realized that I need to pass more complex data from my JSON which ...

Setting various colors for different plots within a single chart: A step-by-step guide

I'm currently tackling a project that requires me to showcase two different plots on the same chart, one being a "SPLINE" and the other a "COLUMN". My aim is to assign distinct background colors to each of these plots. Please note that I am referring ...

Tips for integrating an arrow function as a property in a functional programming approach using JavaScript or TypeScript

Suppose I were to create a constructor for a functional class with TypeA as an argument, and TypeB representing the type of the class itself. In such cases, I can implement it using: functionName(argument: TypeA): TypeB { this.property = argument; ...

Is there a way to position the Image component from next/image using absolute positioning?

Is it possible to use an element Image from 'next/image' with the CSS style { position: absolute; left: 50% }? It appears that it is not being applied. For example: import React from 'react' import Image from 'next/image' imp ...

Error with Array type encountered in Typescript's find method

I am encountering an issue with code that looks like this: type X = { test: number; x: number; }[]; type Y = { test: number; y: number; }[]; type Z = { test: number; z: number; }[]; export const testFunc = (arg: X | Y | Z) => { return a ...

Angular Material's input field is not correctly binding to localeString

I'm currently utilizing Angular Material 11.2, and I have a specific need to convert the inputted string into US dollars format. My attempts so far include: <input matInput formControlName="test" (onkeyup)="onKeyUpTest($event)" ...

Why don't my absolute paths work on nested folders in React and Typescript?

Struggling to configure absolute paths in my React project, encountering challenges with nested folders and the use of @ prefix. Here's what I have set up in my tsconfig.json: { "compilerOptions":{ "baseUrl":"src", ...

Tips for determining the datatype of a callback parameter based on the specified event name

Let's say we have the following code snippet: type eventType = "ready" | "buzz"; type eventTypeReadyInput = {appIsReady: string}; interface mysdk { on:(event: eventType, cb: (input: eventTypeCallbackInput) => void) => void } mysdk.on("ready", ...