如何将 JSON 对象的属性从外部请求解析为 Websharper 中的选项?

How do I parse JSON object's properties from external request into Options in Websharper?

我希望能够使用模式匹配从外部 JSON 调用结果的可选属性中安全地提取值。

场景:(以openweathermap api为例)

type MyType = { cod: int option }
let printCod (x:MyType) = match x.cod with
  | Some cod -> Console.Log(cod)
  | None     -> Console.Log("EMPTY")

let success =
  fun (data, _, _) -> 
    let dat = As<MyType> data
    Console.Log(dat.cod.IsSome)  // prints false
    Console.Log(dat.cod.IsNone)  // prints false
    Console.Log(dat.cod)         // prints correct value
    printCod dat                 // prints undefined

    let dat' = {cod = Some 300}
    Console.Log(dat'.cod.IsSome) // prints true
    Console.Log(dat'.cod.IsNone) // prints false
    printCod dat'                // prints 300
    let dat'' = {cod = None}
    printCod dat''               // prints Empty

let config = 
  JQuery.AjaxConfig
    (Url = "http://api.openweathermap.org/data/2.5/weather?q=London,uk", 
     DataType = (JQuery.DataType.Jsonp :?> _), Success = [| success |])

let AjaxCall() = JQuery.JQuery.Ajax(config)

let Main =
  let _ = AjaxCall()
  ...

我希望能够根据我的类型使用 Option 正确处理响应对象。如您所见,As<T> 转换对于这种情况来说不够好。我找不到合适的解决方案。

是否有好的解决方法?

注意:我使用的是 Websharper 3.0

目前无法自动执行此操作。您需要明确转换它:

let optionField<'T> obj name =
    if JS.HasOwnProperty obj name then Some (JS.Get<'T> name obj) else None

type MyType =
  { cod: int option }
  static member FromJson(json: obj) =
    { cod = optionField json "cod" }

然后使用let dat = MyType.FromJson data.

不过您的想法会很有用,我将其添加为 proposal on the websharper github repository

新的 OptionalField 属性已添加到最新的 WebSharper 3.0-alpha。

您现在可以写

type MyType = { [<OptionalField>] cod: int option }

并将选项值作为缺失字段或现有字段存储在 JS 对象中。记录创建、属性 setter 和 getter 以及 RPC 调用都将遵循这一点。