The discussion in implement callable interface is useful but does not completely my answer my question.
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 snippet works but when the overloaded function is uncommented it fails. I've tried various methods and haven't figure out how to implement the overloaded version.
A slightly convoluted but real world implementation I'm trying to understand is fp-ts
style interfaces. Ignoring the complex types it's an overloaded callable interface is what I understand. How would such a thing have a concrete implementation.
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>>
}