I need a type that will be translated into a plain JS object so that F# field access will be translated into simple JS field access (this is necessary, since the object will be sent through postMessage
, so it'll lose all its methods).
Again, I need
let x = a.b
to be translated into
var x = a.b;
without any method calls.
Here is a slightly modified example from the F# Reference:
namespace T
open IntelliFactory.WebSharper
[<JavaScript>]
module A =
type MyClass =
val a : int
val b : int
new(a0, b0) = { a = a0; b = b0; }
let myClassObj = new MyClass(35, 22)
let x = myClassObj.b
This won't translate with
x: error : Failed to translate property access: b.'
Ok, let's make those val
s mutable:
namespace T
open IntelliFactory.WebSharper
[<JavaScript>]
module A =
type MyClass =
val mutable a : int
val mutable b : int
new(a0, b0) = { a = a0; b = b0; }
let myClassObj = new MyClass(35, 22)
let x = myClassObj.b
This will be successfully translated, but… MyClass.New
returns an empty object. The question now starts looking much like a bugreport, right? So, back to the question.
Are there any other ways to achieve what I want?
There are additional issues with record-style constructors "{x = y}". I will have to look into this again on F# 3.0, the older F# did not produce sensible quotations for those and we did some partial workarounds in WebSharper. Right now your example breaks. So here is the working code with a static method instead of a constructor:
type MyClass private () =
[<DefaultValue>]
val mutable a : int
[<DefaultValue>]
val mutable b : int
static member Create(a0, b0) =
let c = MyClass()
c.a <- a0
c.b <- b0
c
let test () =
let myClassObj = MyClass.Create(35, 22)
let x = myClassObj.a
let y = myClassObj.b
JavaScript.Log(x, y)
Trivially, a record would also work.
In some cases where you want to go really low-level you can annotate members with the Inline attribute. When this is too much overhead you can use untyped API:
let x = obj ()
x?a <- 1
let y = x?a
JavaScript.Log(x, y)