ReasonML访问JS记录字段

Abr*_*m P 2 javascript ocaml reason bucklescript

假设我有一个名为 的全局对象Example,它有一个构造函数,该构造new Example()函数返回一个带有名为 的键的对象"Messaging"

假设我有以下原因/Bucklescript 代码:

[@bs.deriving abstract] type example = {
  [@bs.as "Messaging"] messaging: string
};

type wrappedExample = Js.t(example);

[@bs.new] external exampleConstructor: unit => wrappedExample = "ExampleThing";

exampleConstructor()#messaging;
Run Code Online (Sandbox Code Playgroud)

这导致:

This expression has type wrappedExample
It has no method messaging
Run Code Online (Sandbox Code Playgroud)

将最后一行更改为:

exampleConstructor()##messaging或exampleConstructor().messaging同样失败。这里有什么问题呢?我如何访问我的 javascript 值?

https://reasonml.github.io/en/try?rrjsx=true&reason=NoAQRgzgdAJgpgJwJYDckDsDmACAhpAFwVwGMCBdbAgTwAc5s4APXAW1oBsGBebAbwBQ2bKEhRcEbACIAsnAgRcmDJimVW8xcqwAubBCIqBAXwDcAgTXrYA7sVr0YAURb su2XgCloBABTM2TjgaASnMBUWh0OBtKZgJEdFwORlcggGEAe3QDBABXMgyEPVz0JAIPAD5be0cXQPdeKTq3OAAVAAsVKTCAlszsonyCQt9ggGINBSUVUyA

gle*_*nsl 5

您似乎在这里混淆了一堆相似的东西,但实际上并不能协同工作。

首先,#用于访问 OCaml 对象的字段。##用于访问对象的字段Js.t,这不是您这里所拥有的(我将立即解释原因)。

[@bs.deriving abstract]是一个不同的概念Js.t,不会创建任何类型的对象类型,而是生成一个抽象类型(这就是注释abstract中bs.deriving暗示的内容)。抽象类型本身没有“结构”,因此您不能直接用它做任何事情。并且将其包装起来Js.t并不会使其成为 JS 对象类型,而只是包装的抽象类型Js.t(Js.t对象类型具体是包装在 中的 OCaml 对象类型Js.t)。

关键是[@bs.deriving abstract]不仅创建抽象类型,还创建许多对其进行操作的函数。对于每个字段,它都会创建一个后缀为Get,messagingGet的 getter,如果可变,则创建一个后缀为 的 setter Set。还有一个以类型命名的创建函数,并将字段作为标记参数,因此在您的情况下,您可以使用example(~messaging="whatever"). 有关详细信息,请参阅BuckleScript 文档。

这是您的示例的固定版本:

[@bs.deriving abstract] type example = {
  [@bs.as "Messaging"] messaging: string
};

[@bs.new] external exampleConstructor: unit => example = "ExampleThing";

exampleConstructor() |> messagingGet;
Run Code Online (Sandbox Code Playgroud)

如果您认为这一切非常令人困惑,那是因为事实确实如此。我不知道他们在做什么,但对我来说似乎也很混乱。我建议[@bs.deriving abstract]完全跳过,而是使用普通的 s 自己创建抽象类型和访问器external。这样一来,就不会那么令人困惑的魔法和可怕的事物命名了。