Change number-type object fields to string representation

I am in the process of creating a function that takes an object as input and converts all number fields within that object to strings. My goal is for TypeScript to accurately infer the resulting object's fields and types, while also handling nested structures seamlessly.

Below is a snippet of the current implementation which lacks type safety:

import _ from 'lodash'

export const numbersToString = <T extends object>(obj: T) => {
  obj = _.cloneDeep(obj)

  _.keys(obj).forEach((key) => {
    if (_.isNumber(obj[key])) {
      obj[key] = String(obj[key])
    } else if (_.isArray(obj[key])) {
      obj[key] = obj[key].map((el) => (_.isObject(el) ? numbersToString(el) : el))
    } else if (_.isObject(obj[key])) {
      obj[key] = numbersToString(obj[key])
    }
  })

  return obj
}

Answer №1

The solution to the question can be found here:

If anyone is looking for the answer, this code snippet below provides the solution:

import _ from 'lodash'

type ConvertNumbersToStrings<T> = {
  [k in keyof T]: T[k] extends number ? string : T[k] extends object ? ConvertNumbersToStrings<T[k]> : T[k]
}

export const numbersToString = <T extends object>(obj: T): ConvertNumbersToStrings<T> => {
  obj = _.cloneDeep(obj)

  _.keys(obj).forEach((key) => {
    if (_.isNumber(obj[key])) {
      obj[key] = String(obj[key])
    } else if (_.isArray(obj[key])) {
      obj[key] = obj[key].map((el) => (_.isObject(el) ? numbersToString(el) : el))
    } else if (_.isObject(obj[key])) {
      obj[key] = numbersToString(obj[key])
    }
  })

  return obj
}

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 can I enhance the appearance of an Angular 4 component using an attribute?`

There is a component where I need to pass specific data to the child components within an ngFor loop using attributes. Depending on the attribute, I want to style these child components accordingly. Code testimonials.component.html - (Parent component) ...

Converting an integer into a String Enum in TypeScript can result in an undefined value being returned

Issue with Mapping Integer to Enum in TypeScript export enum MyEnum { Unknown = 'Unknown', SomeValue = 'SomeValue', SomeOtherValue = 'SomeOtherValue', } Recently, I encountered a problem with mapping integer val ...

Tips for adjusting the angle in SVG shapes

I have designed an svg shape, but I'm struggling to get the slope to start from the middle. Can someone please provide assistance? <svg xmlns="http://www.w3.org/2000/svg" fill="none"> <g filter="url(#filter0_b_1_2556)"&g ...

Restrict the properties of an object to match the properties of a different object

I am currently developing an Object patching utility function with the following code snippet class Test{ a:number; b:number; } var c:Test={a:0,b:1} function patchable<T>(obj:T){ return { patch:function<K>(prop:K){ return patc ...

Encountering an error with the iconv-lite package in TypeScript code

I recently added the "iconv-lite" package to my project, imported the module, and attempted to use the decode method. However, I encountered the following error: TypeError: Cannot read properties of undefined (reading 'decode') Interestingly, ...

Retrieve a specific number from an equation

With my limited knowledge of TypeScript, I am attempting to extract a specific number from an expression. The goal is to locate and retrieve the digit from the following expression. ID:jv.link.weight:234231 In the given string, I aim to extract the numb ...

Activating functions based on radio button selection in React with TypeScript

Below are the radio buttons with their respective functions: <div className="row"> <div className="col-md-4"> <label className="radio"> <input onChange={() => {serviceCalc()}} ty ...

Angular is unable to iterate through a collection of ElementRef instances

My list of ElementRef contains all my inputs, but adding listeners to them seems to indicate that textInputs is empty even though it's not. @ViewChildren('text_input') textInputs!: QueryList<ElementRef>; ngAfterViewInit(): void { ...

Using TypeScript's reference function within an HTML document

It feels like ages since my early days of web development. Back when I first started coding, we would reference a script using a <script> tag: <html> <head> <script src="lealet.js"></script> <!-- I know the path isn´t c ...

AutoAnimate animation customization is not compatible with React

I'm in the process of integrating a plugin from this source into my code. I've made adjustments to it for React, but it's still not working as expected. Can you assist me with resolving this issue? Custom Hook: import { useRef, useLayoutEff ...

Converting TypeScript to ES5 in Angular 2: A Comprehensive Guide

I am currently diving into Angular 2 and delving into Typescript to create simple applications within the Angular 2 framework. What I have discovered is that with Typescript, we can utilize classes, interfaces, modules, and more to enhance our application ...

Pay attention to the input field once the hidden attribute is toggled off

In attempting to shift my attention to the input element following a click on the edit button, I designed the code below. The purpose of the edit is to change the hidden attribute to false. Here's what I attempted: editMyLink(i, currentState) { ...

Invoking a function containing an await statement does not pause the execution flow until the corresponding promise is fulfilled

Imagine a situation like this: function process1(): Promise<string> { return new Promise((resolve, reject) => { // do something const response = true; setTimeout(() => { if (response) { resolve("success"); ...

The scrolling experience in Next js is not as smooth as expected due to laggy MOMENTUM

Currently, I am in the process of constructing my portfolio website using Next.js with Typescript. Although I am relatively new to both Next.js and Typescript, I decided to leverage them as a learning opportunity. Interestingly, I encountered an issue with ...

How to share data between two different components in Angular 6

I have a component called course-detail that fetches data (referred to as course) from my backend application. I want to pass this data to another component named course-play, which is not directly related to the course-detail component. The goal is to dis ...

What could be causing the radio button to not be checked when the true condition is met in Angular?

I am working on an angular7 application that includes a dropdown list with radio buttons for each item. However, I am facing an issue where the radio button is not checked by default on successful conditions. Below is the code snippet from my component.htm ...

What steps are necessary to integrate barrel file imports with my Angular 2 application?

Following the Angular 2 style guideline 04-10 Create and Import Barrels can be challenging, as it may lead to unexpected file loading issues. When running my app, I noticed that Angular attempts to load a non-existent file named "my-component-name-here.js" ...

Ways to verify if an item is an Express object?

Currently, I am utilizing typescript to verify whether an app returned by the Express() function is indeed an instance of Express. This is how I am attempting to accomplish this: import Express from "express" const app = Express() console.log( ...

What are the steps for creating and deploying a project that utilizes asp.net core on the server-side and Angular on the client-side

My latest project combines asp.net core 5 and angular 15 technologies for the backend and frontend, respectively. The asp.net core MVC portion of the project is contained in a dedicated folder named serverApi, while the angular part is generated in another ...

What causes an interface to lose its characteristics when a property is defined using index signatures?

Here's the code snippet I'm having trouble with, which involves tRPC and Zod. import { initTRPC, inferRouterOutputs } from '@trpc/server'; import { z } from "zod"; const t = initTRPC.create(); const { router, procedure } = t; ...