簡體   English   中英

如何在 ReScript 中將 Js.Dict.t 轉換為 Js.t?

[英]How to convert a Js.Dict.t to Js.t in ReScript?

有沒有一種直接的方法來轉換像這樣的Js.Dict.t

Js.Dict.fromArray([
    ("bigKey", Js.Dict.fromArray([("smallKey", "value")]))
])

像這樣的Js.t

{
    "bigKey": {
        "smallKey": "value"
    }
}

在結構方面它們已經相同——都表示為 JavaScript 個對象——因此從技術上講沒有必要“轉換”它。 盡管在結構上相同,但類型在相互排斥的方式上有所不同,因此通常無法將一個轉換為另一個。

Js.Dict.t是一個未知數量的鍵值對的同構集合,而Js.t是一個固定數量的鍵值對的異構集合,雖然它也支持子類型化,結合類型推斷可能會出現是動態的。

因此,關於它的 go 最簡單的方法是將其轉換為“開放的” object 類型,該類型將被推斷為您想要的任何類型:

external dictToJsObject : Js.Dict.t(_) => Js.t({..}) = "%identity";

但要注意這里的鍵沒有類型安全。 編譯器只會假設您使用它是正確的。 如果您使用一個鍵,則假定它存在,並且來自Js.Dict.t的值的類型約束不會被繼承並且跨鍵不一致。

稍微好一點的方法是將其轉換為“封閉的” object 類型,具有已知的形狀:

external dictToJsObject : Js.Dict.t('a) => Js.t({ "foo": 'a, "bar": 'a }) = "%identity";

這里返回的 object 被指定為具有與Js.Dict.t相同的值類型的鍵foobar 這提供了明顯更高的類型安全性,但我們仍然無法在編譯時知道foobar鍵是否實際存在於Js.Dict.t中。 我們只是假設它確實如此。

因此,將Js.t轉換為Js.Dict.t的唯一正確方法通常是手動執行:

let dictToJsObjec
  : Js.Dict.t('a) => option({"foo": 'a, "bar" 'a})
  = dict =>
    switch ((Js.Dict.get(dict, "foo"), Js.Dict.get(dict, "bar"))) {
    | (Some(foo), Some(bar)) => Some({
        "foo": foo,
        "bar": bar,
      })
    | _ => None
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM