从 F# Fable 调用 ES 3rd 方脚本方法

Calling ES 3rd party script method from F# Fable

我试图让 Fable 正确编译以下代码,但我无法这样做:

module AppView
#r "../../../node_modules/fable-core/Fable.Core.dll"
open Fable.Core
open Fable.Import.Browser
open Fable.Core.JsInterop
[<Import("default", from="../../../js/3rd/riot.js")>]
module riot_js =
  let mount:((string*obj)->array<obj>) = jsNative

type App
  (
    tagName:string
    ,state
    ,store
  ) = 
  member public x.AppTag =
    (riot_js?mount ("app", state))
    // does not compile: The value or constructor 'riot_js' is not defined.
    // (riot_js.mount ("app", state))
    // compiles wrongly to: riot_js.mount(["app", this.state]);

尝试 riot_js?mount 会神奇地导致 riot_js 不再存在,而尝试 riot_js.mount 会编译成 riot_js.mount(["app", this.state]);

Mount 不接受一个参数,而是接受 2 个参数,但它要么不会转译,要么转译错误。

现在我有一个看起来最奇怪的解决方案:

[<Emit("riot_js")>]
let riot_js (x: int): obj = jsNative
...
((riot_js 1)?mount ("app", state))

这个 returns 一个数组,但是 Fable 又一次不允许我以 "normal" 的方式获取第一个元素:

((riot_js 1)?mount ("app", state))?[0]

[ 上显示红色,错误 Unexpected symbol '[' in expression. Expected identifier, '(' or other token.

((riot_js 1)?mount ("app", state)).[0]

出现错误的所有内容都显示为红色 The field, constructor or member 'Item' is not defined.

以下"works"

((riot_js 1)?mount ("app", state))?``0``

并编译为:

riot_js.mount("app", this.state)["0"];

这不是最好的结果。我会让这个问题搁置一段时间,并设置一个一周左右的赏金,然后再用寓言打开 2 个问题。

以下似乎可以编译为正确的 ES,并且不需要 ? 所以它将是强类型的。

open Fable.Core.JsInterop
type Riotjs = 
  {
    mount:(System.Func<string,obj,string []>)
  }
let riot = (importAll<obj> "../js/3rd/riot.js") :?> Riotjs
let app = riot.mount.Invoke("app",(createObj []))

我将初始状态设置为类型 obj 但也可以使用强类型应用程序状态。

生成的 ES 是:

export var app = riot.mount("app", {});