TypeScript index signature with promises

199 views Asked by At

What is the correct index signature for the following class?

class MyClass {
  [index: string]: Promise<void> | Promise<MyType>; // not working

  public async methodOne (): Promise<void> { ... }
  public async methodTwo (): Promise<MyType> { ... }
}

I want to be able to execute a method on this class using the string name of the method:

myClassInstance[stringNameOfMethodOne]()

There are two TypeScript errors, one on the method definition and one on the usage of the method. The method definition error is:

Property 'methodOne' of type '() => Promise<void>' is not assignable to 'string' index type 'Promise<void> | Promise<MyType>'

The error on the usage of the method is:

This expression is not callable. No constituent of type 'Promise<MyType> | Promise<void>' is callable.

I've done this in JavaScript but am less familiar with TypeScript's index signatures.

2

There are 2 answers

0
ghybs On BEST ANSWER

You probably just forgot the function type:

class MyClass {
  [index: string]: () => (Promise<void> | Promise<MyType>); // A function type returning a Promise

  public async methodOne (): Promise<void> { ... }
  public async methodTwo (): Promise<MyType> { ... }
}
0
Alex Wayne On

You may not want an index signature at all. Because this works fine:

interface MyType { myType: true }

class MyClass {
  public async methodOne (): Promise<void> {}
  public async methodTwo (): Promise<MyType> { return { myType: true } }
}

const stringNameOfMethodOne = 'methodOne'
const myClassInstance = new MyClass()
myClassInstance[stringNameOfMethodOne]() // works

stringNameOfMethodOne here is actually a string literal type, so typescript knows exactly what property it will look up, which makes everything work.