Error encountered when attempting to access an instance property or method using dynamic input within the square brackets in Typescript

Here is the code snippet that I am working with:

class Label{
  constructor(
    public name:string='name',
    public configPath:string='path',
    public foo:{bar:string} = {bar:'hello'}
  ){

  }
}

const labelName:string = 'bob'
const configPath:string = './path/to/a/config.file'
const label_name = new Label(labelName, configPath);

function line(line: string):void {
  const regex = /\./g;
  let path = line.split(regex);
  let startingObj = label_name;
  function addPath(path: string) {
    startingObj = startingObj[path];
  }
  path.forEach(addPath);
  console.log(startingObj);
}

line('name')
line('foo.bar')

The purpose of the line function is to allow me to retrieve and log elements through a terminal request. While I acknowledge that directly accessing class members in this manner may have its risks, for development purposes, I find it suitable. The format for line should be similar to report.q1, and the logged values should appear in the console.

When using TypeScript, an error arises with startingObj = startingObj[path];, specifically:

Element implicitly has an 'any' type because expression of type 'string' >can't be used to index type 'Label'. No index signature with a parameter of >type 'string' was found on type 'App'.ts(7053)

To provide further clarity, I have set up a demo on the TypeScript playground.

How can I resolve this error in TypeScript?

Answer №1

Upon delving deeper into Typescript documentations, I uncovered the root cause of the issue and managed to find a resolution by experimenting with it in a playground:

// TypeScript code snippet
class Label {
  constructor(
    public name: string = 'name',
    public configPath: string = 'path',
    public foo: { bar: string } = { bar: 'hello' }
  ) {
  }
}

const labelName: string = 'bob';
const configPath: string = './path/to/a/config.file';
const label_name = new Label(labelName, configPath);

function line(line: string): void {
  const regex = /\./g;
  let path = (line.split(regex) as unknown) as KeysOfStartingObj[];
  let startingObj = (label_name as unknown) as Object;

  type KeysOfStartingObj = keyof typeof startingObj;
  function addPath(path: KeysOfStartingObj) {
    startingObj = startingObj[path];
  }
  path.forEach(addPath);
  console.log(startingObj);
}

line('name');
line('foo.bar');

The issue stemmed from TypeScript's lack of knowledge regarding the keys within the startingObj. By defining

type KeysOfStartingObj = keyof typeof startingObj
, I created a type that encompasses all keys present in startingObj. Using
let path = (line.split(regex) as unknown) as KeysOfStartingObj[];
informed TypeScript that the split string array consists of elements matching KeysOfStartingObj. Additionally, in the function signature, I specified that the argument path should adhere to this same type, consequently silencing TypeScript's complaints =).

While there are improvements to be made in the function to ensure that only valid object keys are processed, my primary goal was simply to resolve the error raised by TypeScript. This newfound solution could potentially benefit others facing similar challenges!

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

TypeScript Generics: Property types do not match (the properties listed are missing)

In the code snippet below, I've defined an interface, type, and a function. interface ActionWithGeneric<T> { type: 'add' | 'remove'; data: T; } type StateWithGeneric<T> = Array<ActionWithGeneric<T>> ...

Input a new function

Trying to properly type this incoming function prop in a React Hook Component. Currently, I have just used any which is not ideal as I am still learning TypeScript: const FeaturedCompanies = (findFeaturedCompanies: any) => { ... } This is the plain fun ...

Using Typescript to create a generic return type that is determined by the type of a property within an object union

Consider the following scenario: type Setting = { key: "option_one", value: number, } | { key: "option_two", value: string, } export type SettingKey = Setting["key"]; // "option_one"|"option_two ...

Having difficulty invoking the forEach function on an Array in TypeScript

I'm currently working with a class that contains an array of objects. export interface Filter { sf?: Array<{ key: string, value: string }>; } In my attempt to loop through and print out the value of each object inside the array using the forE ...

Creating TypeScript domain objects from JSON data received from a server within an Angular app

I am facing a common challenge in Angular / Typescript / JavaScript. I have created a simple class with fields and methods: class Rectangle { width: number; height: number; area(): number { return this.width * this.height; } } Next, I have a ...

Is there an issue with this return statement?

retrieve token state$.select(state => { retrieve user access_token !== ''}); This error message is what I encountered, [tslint] No Semicolon Present (semicolon) ...

Error in Angular TypeScript occurs when attempting to read properties of an undefined value

Here is the interface that I am working with: export interface IQuest { Id: number, lat: number, lon: number, Question:string, Answer:boolean, IsDone:boolean, Correct:boolean, Range:number} Along with the following component: export class AppComponent imp ...

Previewing multiple selected files in Angular interface

As a newcomer to Angular, I am currently working on a feature that involves selecting multiple files and displaying their previews before uploading them to the server. While my code works correctly when individual files are selected one at a time, it fail ...

Angular 2 child route causing application to become unresponsive

Hey there, I'm currently working on setting up child routes for my Angular app and this is what I have so far: import {bootstrap} from 'angular2/platform/browser' import {CommercifyComponent} from './commercify.component' import { ...

Do you think it is essential to run NPM install?

I am developing an NPM library that utilizes socket.io and is being written in Typescript. Imagine my library contains a function like this: public someFunction = (_socket: Socket) => {} When using my library in an application, only this function is ...

Iterate over the key-value pairs in a loop

How can I iterate through a key-value pair array? This is how I declare mine: products!: {[key: string] : ProductDTO}[]; Here's my loop: for (let product of this.products) { category.products.push((product as ProductDTO).serialize()); } However, ...

The value of "x" cannot be altered, yet it remains unrestricted

In my Angular 10 project with Typescript 3.9, I have the following class definition: export class Document { constructor( public id: number, ... public tags: Tag[] ) { this.id = id; ... this.tags = ta ...

In Typescript, try/catch blocks do not capture return values

I am currently working on a function that performs database operations, with the implementation contained within a try/catch block. Here is an example: async function update({id, ...changes}): Promise<IUserResult> { try { //insert code here retu ...

Is it possible to define a TypeScript class inside a function and access its parameters?

For example, in the world of AngularJS, you might see a construction like this: myApp.factory('MyFactory', function(injectable) { return function(param) { this.saySomething = function() { alert("Param=" + param + " inject ...

Inconsistency with Angular 4 instance variables causes ambiguity within a function

Here is the code snippet: @Component({ selector: 'unb-navbar', templateUrl: './navbar.html' }) export class NavbarComponent implements OnInit { @Input() brand: string; controlador:boolean=false; overlay:string=""; @Input() menu ...

Create a new project using Firebase Functions along with a Node.js backend and a React.js frontend

In the process of developing my application, I have chosen to utilize node.js, express.js, and Firebase with firebase functions, all coded in TypeScript. For the client side framework, I am interested in incorporating react.js. Currently, I have set up nod ...

"What is the best way to specify a type for the src attribute in a tsx file within a

<Image src= { sessionData?.user.image} alt="user" width={100} height={100} />` An issue has been encountered: There is a type error stating that 'string | null | undefined' cannot be assigned to type 'stri ...

An error occurred while trying to load the configuration "next/core-web-vitals" for extension

If you're embarking on a new project using NextJs and TypeScript, chances are you may encounter the following error: Failed to load config "next/core-web-vitals" to extend from. Wondering how to resolve this issue? ...

What is the best way to showcase a view on the same page after clicking on a link/button in Angular?

Is there a way to show a view on the same page in an Angular application when a link is clicked? Rather than opening a new page, I want it displayed alongside the list component. How can this be accomplished? Here's an illustration of my goal: I&apos ...

Is there a way to eliminate the right margin in React?

I am currently working with React to layout three elements below the topElement. My goal is to have these 3 elements fill up the space equally beneath topElement, removing the right-hand gap highlighted in red in the provided image (while keeping the gap a ...