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!
The index signature consists of the index name and its type in square brackets, followed by a colon and the value type: { [indexName: KeyType]: ValueType } . KeyType can be a string , number , or symbol , while ValueType can be any type.
Index signature is used to represent the type of object/dictionary when the values of the object are of consistent types. Assume that we have a theme object which allows us to configure the color properties that can be used across the application. The values will be consistent with the type string.
In TypeScript we can express its type as: ( a : number , b : number ) => number. This is TypeScript's syntax for a function's type, or call signature (also called a type signature). You'll notice it looks remarkably similar to an arrow function—this is intentional!
The error "Property is incompatible with index signature" occurs when a property is not compatible with the specified type of the index signature. To solve the error, change the type of the property or use a union to update the type in the index signature.
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];
}
...
}
Another solution can be:
class MyClass {
public static myMethod(variable:any):string{
}
}
interface Indexable {
[key:string]:any;
}
export const MyExportedClass = MyClass as Indexable;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With