Specify method's type without converting the method to property

There's an existing suggestion at microsoft/TypeScript#22063 to allow function statements (and presumably method definitions) to be typed using a function/callable type alias or interface. Doesn't look like there's much traction there, but if you believe you have a strong use case, you might want to go there and give it a 👍 or comment.


In the absence of that feature, what if you were to create an interface that your class needs to implement, like this?

type LibDoStuffMethodType = (x: string, y: number) => boolean
interface DoStuffMethod { doStuff: LibDoStuffMethodType };

class MyApp implements DoStuffMethod {
  doStuff(a: string, b: number) {
    return true;
    // delegate to external library's lib.doStuff
  }
}
declare const myApp: MyApp;
myApp.doStuff; // looks like a method now

The class MyApp now has a bona fide method named doStuff, but it is constrained to be of type LibDoStuffMethodType!


This works as far as it goes, but I suspect you'll be unhappy that you need to strongly type the method's parameters and return type. It would be great if these would be automatically inferred from the interface DoStuffMethod, but unfortunately this is not currently possible (see microsoft/TypeScript#1373). Which means that I expect any straightforward solution to your problem will require some duplication.

Are there ways around this? Well, if LibDoStuffMethodType is a single (no overloads) specific (no generics) function type, you can use the Parameters<T> and the `ReturnType utility types to annotate the parameter list and return type programmatically:

class MyApp implements DoStuffMethod {
  doStuff(...args: Parameters<LibDoStuffMethodType>): ReturnType<LibDpStuffMethodType> {
    return true;
    // delegate to external library's lib.doStuff
  }
}

That is DRYer, but there are so many caveats that I don't know if it's a good fit for you. I don't know if there are other workarounds, but I suspect they will all have similar issues.

That's the closest I can get.