Issue
interface SomeInterface {
someMethod<T>(): T
}
type SomeType = {
[key in keyof SomeInterface]: ReturnType<SomeInterface[key]>
}
Is it possible to use generic of the someMethod in the SomeType type? How?
I hoped for something like ReturnType<(SomeInterface[key])<string>>
But it clearly doesn't work.
Solution
TypeScript's type system lacks the expressiveness required to programmatically extract type parameters from generic function types. For that we'd probably need either higher kinded types as requested in microsoft/TypeScript#1213, or possibly generic values as requested in microsoft/TypeScript#17574. Even with those features I'm not sure how one could use them to do what you want. Right now this seems to be just beyond the language's abilities.
There are a few features which you could try to use, such as higher order type inference from generic functions or instantiation expressions, but both of those require that you have a value of the relevant generic function type. That is, you have to "drop down" from the type level to the value level to work with these features, and then try to "lift" the resulting value back up to the type level. They can't really be abstracted, so you can't use them in mapped types.
The closest I could get here would be:
interface SomeInterface {
someMethod<T>(): T
otherMethod(): number;
}
declare const si: SomeInterface;
type SomeType = {
[K in keyof SomeInterface]:
K extends "someMethod" ? ReturnType<typeof si.someMethod<string>> :
ReturnType<SomeInterface[K]>
}
/* type SomeType = {
someMethod: string;
otherMethod: number;
} */
Where we explicitly pretend to have a value vi of type SomeInterface, which is bad enough. Then we need to explicitly grab its someMethod property in order to use an instantiation expression. This explicit reference to someMethod would have to be repeated for each generic method of SomeInterface. So at the end we get the right type, but it doesn't scale.
Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.