Is there a more dynamic way to define key-value pairs in a Typescript model declaration without hardcoding each value in the model file?

We are currently facing a challenge where one of our database tables contains columns with generic names (such as name, id, address, details_column_1, details_column_2, detail_column_3, …details_column_n). These column names are already being used by existing applications, so changing the table structure is not an option. This issue exists in more than one table.

The WEB API response for this table looks something like this:

{
    name: ‘xyz’,
    id: 123456,
    address: [‘address lines’],
    details_column_1: [], 
    details_column_2: [], 
    detail_column_3: [], 
    …
    …
    details_column_n: []
}

We are now attempting to create an interface model for this in Typescript, and as we add each similar item, the model keeps growing:

export interface ClientDetails {
    id: number;
    name: string;
    address: array | null;
    detail_column_1: array | null;
    detail_column_2: array | null;
    detail_column_3: array | null;
    …
    …
    detail_column_n: array | null;
}

Is there a way to dynamically generate key-value pairs without hardcoding each value in the model file? We have around 50 columns like this and need a simple solution that does not require modifying existing application columns or responses.

Answer №1

A solution exists, but it requires utilizing TypeScript 4.1.

1. Establish a Number Range for n

As TypeScript does not currently accommodate number range types, we can dynamically create one.

range = n => Array.from({length:n},
  (_,i) => i === 0 ? `type Range = ${i}` : `|${i}`).join("")

range(5) // defines detail columns for n=5
// or
copy(range(5)) // use Firefox to copy type directly to clipboard
When executed in the browser console, the outcome will be:
type Range = 0|1|2|3|4

2. Formulating ClientDetails

export interface ClientDetails extends RepeatGroup {
    id: number;
    name: string;
    address: Array<unknown> | null;
}

type RepeatGroup = { [K in `detail_column_${Range}`]: Array<unknown> | null }

declare const t1: ClientDetails
t1.id // number
t1.detail_column_1 // unknown[] | null
t1.detail_column_4 // unknown[] | null

Explore a working demo here.

Note: In case TS 4.1 is inaccessible, consider using the above method or the TS compiler API to generate the complete ClientDetails type.

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

Scraping Wikipedia data using looping in the R programming language

I want to gather information on celebrity and notable deaths for analysis. The structure of Wikipedia's HTML paths for notable dates of death is very consistent, following this format: https://en.wikipedia.org/wiki/Deaths_in_"MONTH"_"YEAR" For insta ...

Issue with accessing global variable in nested function using "this" in Angular 2

Having recently delved into Angular 2, I find myself facing a challenge with accessing the "task_title" within the startTimer() function. The console.log() returns undefined and I suspect it's due to "this" referring to the function itself instead of ...

I'm struggling to grasp the concept of how arrays function

Currently, I am working on a project that requires me to write code for a specific array loop. However, I am struggling to grasp the step-by-step process of how it functions. Could someone please provide an explanation? The purpose of this loop is to cal ...

Issue encountered when uploading Angular 2.0 Release Candidate 1

While integrating my environment with Django and Python, I encountered an error when trying to upload a file to the Django REST API: 415 unsupported media type. Here is the code snippet: FORM TO UPLOAD BELOW: THE FUNCTION TO CAPTURE THE EVENT: fileChan ...

Securing your Angular application with an SSL certificate and key in the Ng Serve root directory

I am currently attempting to configure a SSL key and certificate on my ng serve using the following command: ng serve --ssl true --ssl-key './assets/somekey.key' --ssl-cert './assets/somecert.cert' However, when I run this command, th ...

Steps to set angular for all items in the dropdown menu:

I am currently working on implementing a dropdown feature within my Angular application. The dropdown will display a list of shops, and when a shop is selected, it will show the content related to that particular shop. I need to add a new item called "ALL ...

Unable to locate module: Issue: Unable to locate '@angular/cdk/tree' or '@angular/material/tree'

Currently utilizing Angular 5 and attempting to create a tree view that resembles a table layout. https://stackblitz.com/edit/angular-hhkrr1?file=main.ts Encountering errors while trying to import: import {NestedTreeControl} from '@angular/cdk/tree ...

`Unable to access variable within the HTML file of a component in Angular`

I have been attempting to show the data from an array (which is populated in chat.component).. public matchesList = []; loadMatches() { ... if (result.success) { this.matchesList = result.matches_list.split(','); console.log(thi ...

Adjust the size of the cursor

Currently, I am in the process of creating a drawing application akin to Paint or Sketchpad. One issue I have encountered is the inability to resize the cursor based on the line width of the pencil I am using. The workaround I have discovered involves usin ...

The method to permit a single special character to appear multiple times in a regular expression

I am currently working on developing a REGEX pattern that specifically allows alphanumeric characters along with one special character that can be repeated multiple times. The permitted special characters include ()-_,.$. For instance: abc_def is conside ...

What is the best way to combine various ngrx selectors together?

I currently have 3 selectors in my index.ts file export const selectDetails = createSelector( // some code ); export const selectTransactionResponse = createSelector( // some code ); export const selectAdditionalDetails = createSelector( // some code ); ...

React - The best method for updating a component when an array changes

As a newcomer to utilizing React hooks, I encountered some challenges with the useEffect hook. Specifically, I have set up a basic comment board for users to post comments and view a list of previously posted comments. My objective is to ensure that each t ...

Function that wraps JSX elements with the ability to infer types through generics

At the moment, this function is functioning properly function wrapElement(elem: JSX.Element) { return ({ ...props }) => React.cloneElement(elem, { ...props }) } I've been using it in this way to benefit from intelliSense for tailwind classes con ...

Utilizing Angular 9's Http Interceptor to Obtain an AWS Access Token

I've been trying to implement AWS access token in an Angular HTTP interceptor by following this guide. However, my code seems to be caught in an infinite loop and I keep receiving a net::ERR_INSUFFICIENT_RESOURCES error. When I console.log the token ...

Error occurred while initiating Angular frontend application with npm

https://i.sstatic.net/JCy3s.png > ng serve sh: ng: command not found npm ERR! code ELIFECYCLE npm ERR! syscall spawn npm ERR! file sh npm ERR! errno ENOENT npm ERR! <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c4b2a ...

What impact does assigning a variable with the type of 'any' have on the type of the variable being assigned?

Consider the code snippet below: let x: string = "hello world" let y: number = 23 let z: any = 23 console.log(typeof x) // "string" console.log(typeof y) // "number" console.log(typeof z) // "number" x = y // Fai ...

What is the best way to create and manage multiple collapsible Material-UI nested lists populated from an array with individual state in React

In my SideMenu, I want each list item to be able to expand and collapse independently to show nested items. However, I am facing the issue of all list items expanding and collapsing at the same time. Here is what I've attempted: const authNavigation ...

Run a Nest.JS Kafka microservice while continuing to listen on port 3000

I have a Nest.JS microservice set up as follows: const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, { transport: Transport.KAFKA, options: { client: { brokers: ['localhost:9092'], } } }); aw ...

Issue: AdonisJS is encountering an error that prevents it from reading properties of undefined (specifically the 'get' property) when attempting to enable

Recently, I started using Adonisjs for building my REST API. However, when I enabled the csrf in ShieldConfig, I encountered the following error: "type": "TypeError", "message": "Cannot read properties of undefined (rea ...

Exploring the Implementation of Prop Types in Vue.js using TypeScript

Check out this code snippet <tr v-for="(item, index) in items"> <td>{{ index + 1 }}</td> <td>{{ item.timestamp }}</td> <td>{{ item.type }}</td> <td>{{ item.message }} ...