Noob interop issue!
Closed this issue · 2 comments
Hi!
I had to write the bindings for Waud JS library by hand and I ended up with the following
As you can see the code for the Waud type and static methods is clearly not what I expect I should be writing:
module Waud =
type Waud =
[<Emit("Waud.autoMute()")>]
static member autoMute() : unit = jsNative
[<Emit("Waud.destroy()")>]
static member destroy() : unit = jsNative
so how could I rewrite this kind of code in a proper fashion? Thanks!
As a funny note, this JS lib is generated from the Haxe transpiler! A great "mise en abîme"
For these cases I recommend to use an interface to the define the JS module as in that case you don't need the Emit
attribute (as long as the JS and F# method names are the same).
type IWaudStatic =
abstract autoMute: unit->unit
abstract destroy: unit->unit
Then you can expose a value with that type and use attribute metadata to tell Fable where it's coming from (global, imported, etc):
[<Global>]
let Waud: IWaudStatic = jsNative
// You can also pass a name if you want to use a different name in F#
[<Global("Waud")>]
let waud: IWaudStatic = jsNative
// If you want to import it, you can use an attribute
[<Import("default", from="waud")>]
let waud: IWaudStatic = jsNative
// ...or an import expression
let waud: IWaudStatic = import "default" "waud"
This is more flexible than having to edit all the Emit attributes for any little change. Using Import
over Global
has the advantage you can specify how the module is actually accessible in your Webpack or Rollup config file.
I hope that helps! :)
Excellent @alfonsogarciacaro! Thanks!