Navigating through an object's keys to access specific properties of another object in TypeScript

Here is the code snippet provided. You can find the full code here

interface DataInterface {
  a: string[];
  b: string[];
  c: number[];
  d: number[];
  e: boolean[];
  x: string
  y: number
}

const dataObject: DataInterface = {
        "a": [
          "{$prefix} {$x}"
        ],
        "b": [
          "temp {$x}"
        ],
        "c": [
          3.8
        ],
        "d": [
          0,
          50
        ],
        "e": [
          true,
          false
        ],
        "x": "world",
        "y": 1,
      }
      
const tableArrays: {[index: string]:any} = {
  a: ["{$prefix} {$x}"],
  b: ["world {$x}"],
  c: [0, 50],
  d: [3.8],
  e: [true,false],
}
for (const tableArray in tableArrays) {
  dataObject[tableArray] = Array.from({
    ...tableArrays[tableArray],
    length: 5,
  })
  dataObject[tableArray].fill(
    tableArrays[tableArray][tableArrays[tableArray].length - 1],
    tableArrays[tableArray].length
  )
  for (let i = 0; i < dataObject[tableArray].length; i++) {
    if (typeof dataObject[tableArray][i] === 'string') {
      dataObject[tableArray][i] = dataObject[tableArray][i].replace('{$x}', i)
      dataObject[tableArray][i] = dataObject[tableArray][i].replace('{$prefix}', "hello")
    }
  }
  if (tableArray === 'b') {
    dataObject[tableArray].pop()
  }
}

console.log(dataObject)

The error encountered reads as follows:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'DataInterface'. No index signature with a parameter of type 'string' was found on type 'DataInterface'.

An attempt has been made to assert that the tableArray variable will only be a key in DataInterface using:

type BuildingTableKeys = keyof BuildingTable;

// Iterate over the keys of tableArrays
for (const tableArray of Object.keys(tableArrays) as BuildingTableKeys[]) {...}

This resulted in the error message:

Conversion of type '{ [index: string]: any[]; }' to type '(keyof DataInterface)[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
The attempt to change to 'unknown' introduced further errors.

Efforts to assert that index is part of DataInterface have also been made using in and keyof, but were unsuccessful:

const tableArrays: {[index: keyof DataInterface]:any}

yielded the error:

An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.

const tableArrays: {[index in DataInterface]:any}

resulted in:

Type 'DataInterface' is not assignable to type 'string | number | symbol'.

Various solutions mentioned here and here were attempted without success.

Answer №1

By expanding the interface and incorporating an index signature, I was able to enhance the data structure.

interface DataStructure {
  a: string[];
  b: string[];
  c: number[];
  d: number[];
  e: boolean[];
  x: string;
  y: number;
}

interface ExtendedDataStructure extends DataStructure {
  [index: string]: any;
}

const newDataObject: ExtendedDataStructure = {
  a: ["{$prefix} {$x}"],
  b: ["temp {$x}"],
  c: [3.8],
  d: [0, 50],
  e: [true, false],
  x: "world",
  y: 1,
};

const updatedTableArrays: Partial<ExtendedDataStructure> = {
  a: ["{$prefix} {$x}"],
  b: ["world {$x}"],
  c: [0, 50],
  d: [3.8],
  e: [true, false],
};

for (const prop in updatedTableArrays) {
  console.log(updatedTableArrays[prop])
  console.log(newDataObject[prop])
}

console.log(newDataObject);

I have concerns about this approach as it allows for arbitrary properties to be added. To address this, I chose to extend the interface rather than directly modify the original one. However, there might still be room for improvement.

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

Can we employ the spread operator in generic parameters?

For instance, when working with ReactQuery's useQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>, I aim to achieve the following: type QueryTypeParams = [Record<string, number>, u ...

Typescript Next.js Project with Custom Link Button Type Definition

I have a project that includes a custom Button component and a NextLink wrapper. I want to merge these two components for organization purposes, but when I combine the props for each, I encounter an issue with spreading the rest in the prop destructuring s ...

Tips on creating type definitions for CSS modules in Parcel?

As someone who is brand new to Parcel, I have a question that may seem naive. In my project, I am using typescript, react, less, and parcel. I am encountering an error with typescript stating 'Cannot find module 'xxx' or its corresponding t ...

In Typescript, object properties make assertions about other properties within the object

I have a specific object that I use to store data received from an API. This object is structured as follows: class Storage { isReady: boolean = false; content: object || null = null; } I have noticed that when isReady is false, content is null. Con ...

error in index of list

UPDATE - Hello, I am facing a challenge with my web development: In my class, there is a method that retrieves a value from a database query (the table in the database contains a key: catId and another field). def getCat(self): ''' ...

Removing fields when extending an interface in TypeScript

Attempting to extend the ISampleB interface and exclude certain values, like in the code snippet below. Not sure if there is an error in this implementation export interface ISampleA extends Omit<ISampleB, 'fieldA' | 'fieldB' | &apos ...

Error in TypeScript occurs when trying to destructure a block-scoped variable before it has been declared

Hello everyone, I have the below code written in TypeScript const { data: { pageCollection } } = await apolloClient.query<PageSlugsQuery>({ query: GET_PAGE_SLUGS }) ( [...(pageCollection?.items ?? [])].forEach((page) => { c ...

What is the correct way to send a GET request in angular?

Trying to make a GET request from Angular to Spring Java, but encountering error code 415 zone.js:3243 GET http://localhost:8080/user/friend/1 415 Below is my Spring Java code for the endpoint: @RequestMapping( value = "/friend/{idUser}", ...

Embed the div within images of varying widths

I need help positioning a div in the bottom right corner of all images, regardless of their width. The issue I am facing is that when an image takes up 100% width, the div ends up in the center. How can I ensure the div stays in the lower right corner eve ...

Create a nested array of subcategories within an array object

Currently, I am working on integrating Django Rest and Angular. The JSON array received from the server includes category and subcategory values. My goal is to organize the data such that each category has its related subcategories stored as an array withi ...

Guard does not prompt router redirection

My angular app running Angular 15 is facing an issue with the App-routing module not redirecting when a guard returns the UrlTree. app-routing.module.ts import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular ...

Creating a regular expression for validating phone numbers with a designated country code

Trying to create a regular expression for a specific country code and phone number format. const regexCountryCode = new RegExp('^\\+(48)[0-9]{9}$'); console.log( regexCountryCode.test(String(+48124223232)) ); My goal is to va ...

Create an array that can contain a mix of nested arrays and objects

Working on my project using Angular and TypeScript includes defining an array that can contain arrays or objects. public arrangedFooterMenu: IMenuItemType[][] | IMenuItemType[] = []; typesOfData.forEach(type => { let filteredData: IMenuItemType | ...

Running cy.task after all test suites can be done by adding the task in a

I need some guidance on running cy.task after executing all test suites. I have a file generated at the start of the tests that I would like to remove once they are completed. Regardless of whether any tests passed or failed, I want to trigger cy.task im ...

Assign a property name in an interface based on the value of another property

Is there a way to define a list of permitted values for a property name in an interface? Let's consider an interface as an example: export interface DashboardRequest { name?: string; description?: string; type: 'foo' | 'bar&apos ...

What are the various methods for increasing a pointer in C, and how do they differ from each other?

Currently, I am learning C and was faced with the challenge of incrementing a pointer in a specific scenario. Let's assume we have this setup: int A[] = {111, 222, 333}; int *q = A;. My goal is to increment the pointer q from the zero-index of array A ...

Guide on effectively testing the catch block of a Typescript function using mocha and chai

In my TypeScript class, I have implemented several functions, each containing a try-catch block that returns a predetermined response upon encountering an error. While writing unit tests using Mocha and Chai, I am facing difficulties in intentionally trig ...

Error encountered when attempting to retrieve response from Java Servlet using HttpClient

I'm encountering an issue where I am receiving a null response in Angular when attempting to post to a httpservlet (Java) in a WebSphere Application Server environment. The objective is to call an API for logging in. However, I am getting a null resp ...

By utilizing a function provided within the context, React state will consistently have its original value

After passing functions from one component to its parent and then through context, updating the state works fine. However, there is an issue with accessing the data inside these functions. They continue to show as the initial data rather than the updated v ...

Error involving ESLint detecting unused variables within a TypeScript generic type

My dilemma lies in the implementation of a straightforward object class designed to restrict potential values to a specific type: export class Dictionary<T> { [key: string]: T } Unexpectedly, ESLint is flagging this code with the message 1:25 e ...