ts2fable
ts2fable copied to clipboard
avoid member overloads
It would be nice to avoid overloads. While working on http://blog.ctaggart.com/2017/11/how-to-create-http2-app-in-f.html, it was a major pain to get the F# compiler to use the correct unique overload, especially with optional parameters and base classes that have identical signatures.

That is from server.listen 8843..
I had issues withe end as well:
type [<AllowNullLiteral>] ServerHttp2Stream =
inherit Http2Stream
type [<AllowNullLiteral>] Http2Stream =
inherit stream.Duplex
abstract ``end``: unit -> unit
abstract ``end``: chunk: obj * ?cb: Function -> unit
abstract ``end``: chunk: obj * ?encoding: string * ?cb: Function -> unit
type [<AllowNullLiteral>] stream.Writable =
abstract ``end``: unit -> unit
abstract ``end``: chunk: obj * ?cb: Function -> unit
abstract ``end``: chunk: obj * ?encoding: string * ?cb: Function -> unit
I was facing the same problem when working with Fable + Express.
My way around it and to propose a better DSL was to use static constraints there can be tedious to write probably.
Express sugar synthax You can see the resulting DSL here. Don't know if this can be useful or no.
Thinking out loud here. How do we solve this case:
type [<AllowNullLiteral>] Http2SecureServer =
inherit tls.Server
type [<AllowNullLiteral>] Server =
inherit net.Server
type [<AllowNullLiteral>] Server =
inherit events.EventEmitter
abstract listen: ?port: float * ?hostname: string * ?backlog: float * ?listeningListener: Function -> Server
abstract listen: ?port: float * ?hostname: string * ?listeningListener: Function -> Server
abstract listen: ?port: float * ?backlog: float * ?listeningListener: Function -> Server
abstract listen: ?port: float * ?listeningListener: Function -> Server
abstract listen: path: string * ?backlog: float * ?listeningListener: Function -> Server
abstract listen: path: string * ?listeningListener: Function -> Server
abstract listen: options: ListenOptions * ?listeningListener: Function -> Server
abstract listen: handle: obj * ?backlog: float * ?listeningListener: Function -> Server
abstract listen: handle: obj * ?listeningListener: Function -> Server
May be something like parameter count and the number of times the parameter count showed up if more than one. The suffix only shows up on overloads.
type [<AllowNullLiteral>] Server =
inherit events.EventEmitter
abstract listen: ?port: float * ?hostname: string * ?backlog: float * ?listeningListener: Function -> Server
abstract listenP3: ?port: float * ?hostname: string * ?listeningListener: Function -> Server
abstract listenP3N2: ?port: float * ?backlog: float * ?listeningListener: Function -> Server
abstract listenP2: ?port: float * ?listeningListener: Function -> Server
abstract listenP3N3: path: string * ?backlog: float * ?listeningListener: Function -> Server
abstract listenP2N2: path: string * ?listeningListener: Function -> Server
abstract listenP2N3: options: ListenOptions * ?listeningListener: Function -> Server
abstract listenP3N4: handle: obj * ?backlog: float * ?listeningListener: Function -> Server
abstract listenP2N4: handle: obj * ?listeningListener: Function -> Server
Good/bad/something better?
Seems a little strange/hard to read.
But it's a good idea to let the classic listen with the derivated methods
As a counterpoint to this issue, I think method overloads are doable if we avoid obj type and had return types that were tied to specific options. See here for more info
Yes, overloads are complicated in F#, that was one of the reasons to create the erased unions instead of automatically generating overloads.
I cannot think of a solution now. If adding a suffix I would like something more meaningful than just the number of parameters, but I know this is hard to with an automatic processor. @jgrund is right in that filling some objs would help the compiler. I've also seen sometimes that removing optional arguments solves the ambiguity (see this commit), maybe we could try to implement an algorithm to see when can this be done.