I have exported a function from some module that looks like:
export function MyFunc<A>() {
return {
foo: (in: A) => void
}
}
Now, in some other module, I want to be able to talk about the different return types of MyFunc. Since I didn't export the type, I'll use typeof to get hold of the type I want given the value MyFunc. Ideally I would do the following:
import { MyFunc } from "mymodule";
type MyFuncReturned<A> = ReturnType<typeof MyFunc<A>>;
function foo(): MyFuncReturned<string> {
// ...
}
Hrmph, this doesn't work; typeof can only be passed a value and doesn't like my attempt to specify the generic type of that value.
The best I can do is convincing TypeScript to infer specific types of MyFunc from values I've created, and then giving them individual type aliases, eg:
const myFuncStringReturn = MyFunc<string>();
type MyFuncStringReturn = typeof myFuncStringReturn;
To avoid actually running MyFunc just to get the type info, I can hide it behind a function and use ReturnType on it:
const myFuncStringReturn = () => MyFunc<string>();
type MyFuncStringReturn = ReturnType<typeof myFuncStringReturn>;
const myFuncBoolReturn = () => MyFunc<bool>();
type MyFuncBoolReturn = ReturnType<typeof myFuncBoolReturn>;
This gives me a way of, one type at a time, talking about the different return types of MyFunc, but it
- Involves actual runtime code to be written that TS can infer from.
- Doesn't let me talk about
MyFuncin a more generic sense.
The only "proper" solution I can come up with is duplicating a bunch of type info when I declare MyFunc:
export function MyFunc<A>(): MyFuncReturns<A> {
return {
foo: (in: A) => void
}
}
export type MyFuncReturns<A> = {
foo: (in: A) => void
}
But now as I change MyFunc, I have to make sure to keep MyFuncReturns in sync with it.
Is there any way I can get hold of a type like MyFuncReturns<A> given just our exported value MyFunc, without having to add runtime code or add the boilerplate above?