我希望能够使用模式匹配从外部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
答案 0 :(得分:1)
最新的WebSharper 3.0-alpha添加了一个新的OptionalField属性。
您现在可以写
type MyType = { [<OptionalField>] cod: int option }
并将选项值存储在JS对象上作为缺失或现有字段。记录创建,属性设置器和getter以及RPC调用都将尊重这一点。
答案 1 :(得分: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。