I'm trying to implement a function map
that takes a function of type Mapper
(a -> b
) and a functor f a
, and returns a functor f b
. I have trouble getting TypeScript to correctly infer the return type of map
.
I define a functor as any object that has a map
method:
type Mapper<a, b> = (arg: a) => b;
interface Functor<a> {
// I have Functor<b> as the return type
// but I'd need something like (generictypeof Functor<a>)<b>
// which I don't know how to do
map<b>(func: Mapper<a, b>): Functor<b>;
}
Now I can define my map
function:
function map<a, b>(func: Mapper<a, b>, functor: Functor<a>) {
return functor.map(func);
}
And use it like so:
const result = map(
(a: number) => a + 1,
[1, 2, 3],
);
This compiles just fine; however, TypeScript tells me that result
is of type Functor<number>
. While I understand why it arrives at that conclusion, how would I need to change my code so that TypeScript can infer that result
is of type Array<number>
?
Any approach I tried so far would require me to extend a Generic type without making it into a concrete type first, or inferring a Generic type from a concrete type (see my comment above), which I can't figure out how to do in TypeScript.