Issue
Let's say, I have a method that delegates its functionality to some method from external library, and I have a type for that external method, e.g. LibDoStuffMethodType
.
class MyApp {
doStuff(args) {
// delegate to external library's lib.doStuff
}
}
Now, how do I specify the type for my method MyApp.doStuff()
? Naturally, I can make the doStuff()
a property of MyApp:
class MyApp {
doStuff: LibDoStuffMethodType
}
But this is undesirable for multiple reasons (one of those is the IntelliSense support, we'd rather see in the IntelliSense suggestions that doStuff()
is an actual method, not a property, methods and properties are colored and marked differently).
So, the question is: is there any way to keep the method as method, but somehow specify its full type LibDoStuffMethodType
?
Solution
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<T>
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.
Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.