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 值?
您似乎在这里混淆了一堆相似的东西,但实际上并不能协同工作。
首先,#用于访问 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。这样一来,就不会那么令人困惑的魔法和可怕的事物命名了。