Call Wails from Fable

wails initで生成されたコードはapp.goGreetメソッドがフロントエンド側に公開されるように設定されている。

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
    return fmt.Sprintf("Hello %s, It's show time!", name)
}

これがfrontend/wailsjs/go/main/App.d.tsfrontend/wailsjs/go/main/App.jsにそれぞれ下記のようにビルドされる。どうやら必ず非同期になるようだがそれはそうか。

export function Greet(arg1:string):Promise<string>;
export function Greet(arg1) {
  return window['go']['main']['App']['Greet'](arg1);
}

これをFableで使うのはこんな感じ。いろいろ思うところはあるがまずは愚直に。

open Fable.Core
open Fable.Core.JS

type IApp =
    abstract Greet: string -> Promise<string>

[<ImportAll("../wailsjs/go/main/App")>]
let app: IApp = jsNative

[<Global>]
let console: JS.Console = jsNative

(app.Greet "world")
    .``then`` (fun s -> console.log s)
|> ignore

App.d.tsの型を用途に合わせたインターフェースにマッピングして各種ImportXxx属性でインポートする方式らしい。then予約語なので何とも言えなさを醸し出している。ついでにconsoleなどはGlobal属性で利用可能だ。

Promiseに関してはFable.Promiseというライブラリでパイプラインまたはコンピュテーション式として扱えるようなのでそれを検討すると良さそう。

型定義ファイルからインターフェースに転写するのダルい問題はts2fableとやらを使うと良さそう。ところでd.ts扱えるTypeProviderはないんだろうか。