0

有没有一种直接的方法来转换Js.Dict.t像这样的

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

喜欢Js.t这个:

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

1 回答 1

0

在结构上它们已经是相同的——两者都表示为 JavaScript 对象——因此在技术上不需要“转换”它。尽管结构上相同,但类型在相互排斥的方式上是不同的,因此通常无法将一种类型转换为另一种类型。

Js.Dict.t是未知数量的键值对的同质集合,Js.t而是固定数量的键值对的异构集合,尽管它也支持子类型化并与类型推断相结合,但它可能看起来是动态的。

因此,最简单的方法是将其转换为“开放”对象类型,该对象类型将被推断为您想要的任何类型:

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

但请注意,此处的键没有类型安全性。编译器只会假设您使用它是正确的。如果您使用一个键,则假定它存在,并且来自 的值的类型约束Js.Dict.t不会被继承并且在键之间不一致。

更好的方法是将其转换为具有已知形状的“封闭”对象类型:

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

这里返回的对象被指定为具有键foo并且bar具有与Js.Dict.t. 这提供了显着更多的类型安全性,但我们仍然无法在编译时知道fooandbar键实际上存在于Js.Dict.t. 我们只是假设它确实如此。

Js.Dict.t因此,通常将 a 转换为 a的唯一正确方法Js.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
    }
于 2020-12-01T14:20:20.197 回答