The thread on implementing a callable interface provides some helpful information, but it doesn't fully address my specific query.
interface lol {
(a: number): (b: number) => string
// (a: string): (b: string) => string // overloaded will not work
}
let l: lol = function(a: number) {
return (b: number) => {
return (a + b).toString()
}
}
This code snippet functions correctly, however uncommenting the overloaded function causes it to fail. I've experimented with different approaches and haven't yet discovered how to incorporate the overloaded version successfully.
An example of a somewhat intricate real-world implementation that I'm trying to comprehend can be found in fp-ts
style interfaces. Despite the complexity of the types involved, it seems to represent an overloaded callable interface. How would one go about implementing such a concept concretely?
export interface Traverse1<T extends URIS> {
<F extends URIS4>(F: Applicative4<F>): <A, S, R, E, B>(
ta: Kind<T, A>,
f: (a: A) => Kind4<F, S, R, E, B>
) => Kind4<F, S, R, E, Kind<T, B>>
<F extends URIS3>(F: Applicative3<F>): <A, R, E, B>(
ta: Kind<T, A>,
f: (a: A) => Kind3<F, R, E, B>
) => Kind3<F, R, E, Kind<T, B>>
<F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
ta: Kind<T, A>,
f: (a: A) => Kind3<F, R, E, B>
) => Kind3<F, R, E, Kind<T, B>>
<F extends URIS2>(F: Applicative2<F>): <A, E, B>(
ta: Kind<T, A>,
f: (a: A) => Kind2<F, E, B>
) => Kind2<F, E, Kind<T, B>>
<F extends URIS2, E>(F: Applicative2C<F, E>): <A, B>(
ta: Kind<T, A>,
f: (a: A) => Kind2<F, E, B>
) => Kind2<F, E, Kind<T, B>>
<F extends URIS>(F: Applicative1<F>): <A, B>(ta: Kind<T, A>, f: (a: A) => Kind<F, B>) => Kind<F, Kind<T, B>>
<F>(F: Applicative<F>): <A, B>(ta: Kind<T, A>, f: (a: A) => HKT<F, B>) => HKT<F, Kind<T, B>>
}