Utilizing string to access property

Is there a better way to access interface/class properties using strings?

Consider the following interface:

interface Type {
  nestedProperty: {
    a: number
    b: number
  }
}

I want to set nested properties using array iteration:

let myType: Type = ...
["a", "b"].forEach(attributeName => myType.nestedProperty[attributeName] = 123)

However, TypeScript complains that "nestedProperty" doesn't have a string index type. Adding a typeguard like if (attributeName === "a")) resolves the error, but I want to avoid using multiple if statements.

Additionally, I don't want to use an indexed type:

interface Type<T> {
  [index:string]: T
  a: T
  b: T
}

Since the structure is not dynamic and properties could have different types.

I've searched through documentation, Stack Overflow, and the web, but haven't found an elegant solution. Should I write a custom guard that returns a union type predicate?

(attribute: string): attribute is ('a' | 'b') { ... }

Answer №1

To ensure TypeScript understands that the array being used only includes valid keys for the nestedProperty property, you need to explicitly declare it.

interface Data {
  nestedProperty: {
    x: string
    y: string
  }
}

// Define a type alias for simplicity. This type represents
// a collection of keys that are permitted in the `nestedProperty`.
type AllowedKeys = Array<keyof Data['nestedProperty']>

// TypeScript now has the assurance that the array is accurate
// and can perform operations confidently.
(["x", "y"] as AllowedKeys).forEach(keyName => myData.nestedProperty[keyName] = "example")

Answer №2

My preference would be:

interface ObjectType {
  properties: {[key in ('x' | 'y')]: number}  
}

let newObj:ObjectType = {
    properties: {
        x: 5,
        y: 10,
    }
};

(["x", "y"] as Array<'x'|'y'>).forEach(propName => newObj.properties[propName] = 321)

While this solution might work for the issue presented, I personally favor explicitly declaring types, as seen in the solution that was accepted.

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

Tips for transferring data to an entry component in Angular 2 using ng-bootstrap modal

I've been grappling with sending data to a custom modal content component in Angular 2. My objective is to have the flexibility of calling this modal from any other component without duplicating code. Despite my efforts, including referencing the "Com ...

Encountering a 405 Error While Trying to Detect Location in Angular 7

I encountered an error 405 (Method Not Allowed) when trying to detect the location. Service public fetchWeatherDataByCoordinates(coordinates: ICoordinates): void { console.log("problem here") this.selectedLocationId.next(this.currentCoordinates ...

Tips for testing two conditions in Angular ngIf

I am facing a little issue trying to make this *ngIf statement work as expected. My goal is to display the div only if it is empty and the user viewing it is the owner. If the user is a guest and the div is empty, then it should not be shown. Here is my cu ...

Receiving an unexpected value from the input attribute

Currently, I am facing a challenge in retrieving data from another component by using the selector in the HTML file of the parent component. Here is how I implemented it: <app-graphs [module]="module" hidden></app-graphs> In the chi ...

When using a Redux action type with an optional payload property, TypeScript may raise complaints within the reducer

In my react-ts project, I define the following redux action type: type DataItem = { id: string country: string population: number } type DataAction = { type: string, payload?: DataItem } I included an optional payload property because there are tim ...

Adjusting various angular-cli configuration files or providing input variables

My application caters to different customers, requiring personalized configurations based on their needs. I am looking for a way to customize the settings in the angular-cli.json file each time I run ng build. Is there a method to: 1) Dynamically cha ...

``There seems to be an issue with the Deno logger FileHandler as it

I am currently in the process of setting up loggers for an application. I have a handler named console which logs every event to the console. Additionally, there is a handler called app that is supposed to log all events to a file. While the logs are succ ...

Incorporating an interface into a data property within a router using TypeScript and Angular

Within the app-routing-module.ts file, utilizing the data property allows us to include custom fields/variables as shown below: ... { path: 'admin-board', loadChildren: './admin-board/admin-board.module#AdminBoardPageModule', dat ...

Storing application state using rxjs observables in an Angular application

I'm looking to implement user status storage in an Angular service. Here is the code snippet I currently have: import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() expo ...

ngPrime table column selection and data extraction

I am looking to extract multiple columns from a table. Can anyone suggest the best approach for this? Does NGPrime offer any functionality for achieving this task? Appreciate your help! ...

Can you use setValidators() in Angular to validate two patterns simultaneously?

Is there a way to validate both IP address and IP address range in a single control using Angular? I have tried using the following code snippet: controls["CapPoolVolExpolAldClientControl"].setValidators([Validators.required, Validators.pattern(/([0-9]){1 ...

Error Encountered with Next.js 13.4.1 when using styled-components Button in React Server-Side Rendering

I am currently working on a React project using Next.js version 13.4.1 and styled-components. One problem I'm facing is with a custom Button component that I've created: import React from 'react'; import styled from 'styled-compone ...

Problem with dynamic page routes in Next.js (and using TypeScript)

Hi everyone, I'm currently learning next.js and I'm facing an issue while trying to set up a route like **pages/perfil/[name]** The problem I'm encountering is that the data fetched from an API call for this page is based on an id, but I wa ...

What are the guidelines for utilizing square brackets [ ] in directives like @Inputs?

I'm feeling a bit lost. Check out this straightforward directive: @Directive({ selector: '[myDirective]' }) export class MyDirective { private textContent: string; private isEnabled: boolean; @Input() myD ...

What is the best way to assign an index signature to a plain object?

Currently, I have this object: const events = { i: 'insert', u: 'update', d: 'delete' }; I am struggling to assign an index signature to the object. When I try the following: export interface EventsSignature { [key: ...

Develop a fresh category inspired by the properties of objects

Let's tackle the challenge of constructing a new type in Typescript based on an descriptive object named schema, which contains all the requirements expressed within it. Here is my proposed solution: type ConfigParameter<IdType, ValueType> = Re ...

Solving issues with malfunctioning Angular Materials

I'm facing an issue with using angular materials in my angular application. No matter what I try, they just don't seem to work. After researching the problem online, I came across many similar cases where the solution was to "import the ...

Is there a way I can keep my ChartJS constantly updated in real time? Currently, it only seems to update when I zoom in or out

I'm looking to create a dynamic graph that updates every 5 seconds or in real-time. I've managed to get it working when zooming in and out of the page, but not when doing nothing. I know it's possible to achieve this, but I can't seem t ...

When working with Angular 2 and Typescript, a common error message that may be encountered is "TypeError

Currently diving into Angular 2 and encountered a stumbling block while attempting to create a service. Despite my efforts in finding a solution, I seem to be missing something crucial. Error: A problem arises in angular2-polyfills.js:1243 with the error ...

Tips on efficiently adding and removing elements in an array at specific positions, all the while adjusting the positions accordingly

My challenge involves an array of objects each containing a position property, as well as other properties. It looks something like this: [{position: 1, ...otherProperties}, ...otherObjects] On the frontend, these objects are displayed and sorted based on ...