Вы, кажется, смешиваете множество вещей, которые похожи, но на самом деле не работают вместе.
Итак, прежде всего, #
используется для доступа к полю объекта OCaml.##
используется для доступа к полю Js.t
объекта, который здесь не тот, который у вас есть (я объясню почему через минуту).
[@bs.deriving abstract]
- это понятие, отличное от Js.t
и не будет создавать тип объекта любого вида, но создает абстрактный тип (это то, на что намекает abstract
в аннотации bs.deriving
).Абстрактный тип не имеет «структуры» сам по себе, поэтому вы ничего не можете сделать с ним напрямую.И перенос его в Js.t
не делает его типом объекта JS, а просто абстрактным типом, заключенным в Js.t
(тип объекта Js.t
, в частности, является типом объекта OCaml, заключенным в Js.t
).
* 1019Ключом к этому является то, что
[@bs.deriving abstract]
не только создает абстрактный тип, но также и ряд функций, которые работают с ним.Для каждого поля он создает получатель с суффиксом
Get
,
messagingGet
в вашем случае, а если изменяемый, то сеттер с суффиксом
Set
.Также есть функция создания, названная в честь типа и с полями в качестве помеченных аргументов, так что в вашем случае вы можете создать объект с
example(~messaging="whatever")
.Подробности смотрите в
документации BuckleScript .
Вот исправленная версия вашего примера:
[@bs.deriving abstract] type example = {
[@bs.as "Messaging"] messaging: string
};
[@bs.new] external exampleConstructor: unit => example = "ExampleThing";
exampleConstructor() |> messagingGet;
Если вы думаете, что все это очень запутанно, то это потому, что это так.Я понятия не имею, что они делают, но мне это тоже кажется очень грязным.Я бы порекомендовал полностью пропустить [@bs.deriving abstract]
и вместо этого создать собственный абстрактный тип и методы доступа самостоятельно, используя обычные external
s.Таким образом, гораздо менее запутанная магия и ужасные названия вещей.