Typescript: creating index signatures for class properties

Encountering a problem with index signatures while attempting to access static and instantiated class properties dynamically. Despite researching solutions online, I have been unable to resolve the issue.

The problem was replicated on a simple class:

interface MyClassInterface {
  name: string;
  getInstanceProperty( propertyName: string ): string;
  getStaticProperty( propertyName: string ): number;
}

class MyClass implements MyClassInterface {

  public name: string;

  private static age: number;

  public constructor( theName: string, theAge: number ) {

    this.name = theName;
    MyClass.age = theAge;

  }

  public getInstanceProperty( propertyName: string ): string {

    return this[propertyName];
    // Typescript error:
    // Element implicitly has an 'any' type because type 'MyClass' has no index signature.

  }

  public getStaticProperty( propertyName: string ): number {

    return MyClass[propertyName];
    // Typescript error:
    // Element implicitly has an 'any' type because type 'typeof MyClass' has no index signature.

  }

}

const myClass = new MyClass( "John", 35 );

console.log(
  myClass.getInstanceProperty( "name" ),
  myClass.getStaticProperty( "age" )
); // Outputs "John 35" in the console

Introducing type information inside the class solves the error for getInstanceProperty() as shown below:

class MyClass implements MyClassInterface {
  [key: string]: any;

  // ...
}

Is it possible to include this modification in the class interface? I have not found a way to do it so far. A similar adjustment may be needed for static properties, but I am unsure how to proceed. Any suggestions?

I have set up this code in the TypeScript Playground. Make sure to enable the noImplicitAny option to see the errors.

Thank you!

Answer №1

For quite some time now, an issue has been raised on TypeScript's GitHub regarding this matter. It appears that having a static index signature is not currently feasible.

To work around this restriction, one possible solution is to assist the compiler by explicitly declaring that your class includes a static index signature using a type assertion like the one shown below.

interface Indexable {
  [key: string]: any;
}

class MyClass {
    ...
    public getStaticProperty( propertyName: string ): number {
      return (MyClass as Indexable)[propertyName];
    }
    ...
}

Answer №2

Here is an alternative approach:

const MyObject = {

    myFunction(param){
        return 'Result';
    }

}

interface Dictionary {
    [key:string]:any;
}

export const ExportedObject = MyObject as Dictionary;

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

Storing information from a form into a database with the help of TypeORM on Angular 6

Utilizing TypeORM alongside Angular to store form data in the database has been successful. The connection configuration is correct, allowing for data storage from the backend. { "type": "mssql", "host": "***", ...

Error: Unable to cast value to an array due to validation failure

I'm currently working on integrating Typegoose with GrqphQL, MongoDB, and Nest.js for a project. My goal is to create a mutation that will allow users to create a post. I have set up the model, service, and resolver for a simple Post. However, when I ...

Combining two streams in RxJS and terminating the merged stream when a particular input is triggered

I am currently developing an Angular application and working on implementing a system where an NGRX effect will make requests to a service. This service will essentially perform two tasks: Firstly, it will check the local cache (sqlite) for the requested ...

Field that only permits numerical input without triggering events for other characters

I've encountered some issues with the default behavior of the HTML number input and I'm looking to create a simple input that only allows numbers. To address this, I have developed a directive as shown below: import { Directive, ElementRef, Hos ...

Creating a blueprint for an object that inherits from another interface

I am looking to create an interface that includes unknown properties for one object, while also extending it with known properties from another interface. Here is my attempt: public async dispatchMessage(): Promise<{} extends IHasResponseFormat> I ...

I am currently struggling with a Typescript issue that I have consulted with several individuals about. While many have found a solution by upgrading their version, unfortunately, it

Error message located in D:/.../../node_modules/@reduxjs/toolkit/dist/configureStore.d.ts TypeScript error in D:/.../.../node_modules/@reduxjs/toolkit/dist/configureStore.d.ts(1,13): Expecting '=', TS1005 1 | import type { Reducer, ReducersMapO ...

Choosing the primary camera on a web application with multiple rear cameras using WebRTC

Having a bit of trouble developing a web app that can capture images from the browser's back camera. The challenge lies in identifying which camera is the main one in a multi-camera setup. The issue we're running into is that each manufacturer u ...

Avoiding repetitive logic in both parent and child components in Angular 8

In my parent controller, I have common requests and I also read router params for those requests. However, for the child components, I have different requests but still need to extract the same parameters from the router - resulting in duplicate code. For ...

Having trouble retrieving spot price using Uniswap SDK due to a transaction error LOK

const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle( immutables.token0, immutables.token1, immutables.fee, amountIn, 0 ) I set up a pool on Uniswap V3 for two ERC20 dummy tokens by using the createPool() met ...

What is the best method for obtaining XML within typescript react in the bpmn-js/lib/Modeler?

After importing my BPMN XML in Model using importXML and setting bpmnModeler to bpmnModelerClone, I now need to retrieve the BPMN from bpmnModelerClone. How can I achieve this? Below is the code snippet showing how I imported XML and set bpmnModeler to bp ...

Guide to successfully passing a function as a prop to a child component and invoking it within Vue

Is it really not recommended to pass a function as a prop to a child component in Vue? If I were to attempt this, how could I achieve it? Here is my current approach: Within my child component - <template> <b-card :style="{'overflow-y&apo ...

Unable to retrieve the third attribute of a Class using Angular2's toString method

Here is the code snippet I am working with: import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Hello {{name}}</h1> <p><strong>Email:</strong> {{email}}< ...

The validator is incorrectly diagnosing the input as 'invalid' when in reality it is not

Currently, I am working on creating a text field that must not be empty and should also not start with a specific set of characters (let's say 'test'). For example, I want testxyz or an empty field to be considered invalid, while anything e ...

Angular: proper dependency injection may not occur when appending .js or .ts at the end of an import statement

When it comes to import statements, the format is usually as follows: import {HelpService} from '../../help.service' It's worth noting that if I utilize autowiring to inject HelpService into the constructor, an already existing instance of ...

Exploring the method to retrieve a dynamically added property in Typescript

My React Component Loader receives certain props. The contentAlign property is only available when the local property exists and its value is 'relative'. I am encountering an error when trying to include contentAlign in the props, and I cannot ...

Implementing indexers in TypeScript to accommodate both string and numeric keys

Seeking to incorporate different types into existing code. In the code, there exists a transitionData object in which objects can be added by index as shown below: this.transitionData[id] = transition where id is a number and transition is of type Trans ...

What is the importance of using getters for functions involving Moment.js in vueJS and typescript?

weekOfMonth() calculates the current month and week within that month. <template> <h3>{{ weekOfMonth }}</h3> </template> <script lang="ts"> export default class HomeView extends Vue { const moment = require(& ...

IE11 and how it handles Typescript and promises

Currently, I am utilizing Typescript version 2.4.2 along with Webpack for compilation purposes. Despite successful compilation, when running my code on IE11, an error 'Promise' is undefined arises. Below is a glimpse of my tsconfig: { "comp ...

Generic parameter with a union type

The proxy function returns a randomly determined type. const numbersArray = [1,2,3,4]; const stringsArray = ['1','2','3','4']; function func<T>(array: T[]): T[][] { return [[array[0], array[1]], [array[2], ...

Using jest to simulate a private variable in your code

I am working on unit testing a function that looks like this: export class newClass { private service: ServiceToMock; constructor () { this.service = new ServiceToMock() } callToTest () { this.service.externalCall().then(()=& ...