5

I am getting an error about index signatures when trying to dynamically access my static and instantiated class properties. I've found a lot of people talking about this error online, but I've not yet been able to fix the issue.

I was able to reproduce the issue 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

I found that it is possible to avoid the error in getInstanceProperty() by adding a type information inside of the class as follows:

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

  // ...
}

Is it possible to add this in the class interface? I haven't managed to do it yet. I suppose that I need a similar modification somewhere for the static properties, but I don't know how to do it. Any idea?

I have reproduced this code in the TypeScript Playground. You just need to enable the noImplicitAny option to show the errors.

Many thanks!

2 Answers 2

4

There has been an open issue on TypeScript's GitHub for a few years around this. It doesn't seem to be possible to have a static index signature currently.

I think the only way around this limitation is to help the compiler out by letting it know that your class has a static index signature by using a type assertion like below.

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

class MyClass {
    ...
    public getStaticProperty( propertyName: string ): number {
      return (MyClass as Indexable)[propertyName];
    }
    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

It works perfectly. Thanks a lot, it's going to be a great help. I haven't played with type assertions yet, but maybe I should look into it. It seems to be quite a powerful tool.
1

Another solution can be:

class MyClass {

    public static myMethod(variable:any):string{

    }

}

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

export const MyExportedClass = MyClass as Indexable;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.