ReasonML доступ к полю записи JS - PullRequest
0 голосов
/ 09 октября 2018

Скажем, у меня есть глобальный объект с именем 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;

В результате:

This expression has type wrappedExample
It has no method messaging

Изменение последней строки на:

exampleConstructor()##messaging или exampleConstructor().messaging аналогично завершается ошибкой.В чем здесь проблема?Как я могу получить доступ к своему значению JavaScript?

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

1 Ответ

0 голосов
/ 09 октября 2018

Вы, кажется, смешиваете множество вещей, которые похожи, но на самом деле не работают вместе.

Итак, прежде всего, # используется для доступа к полю объекта 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.Таким образом, гораздо менее запутанная магия и ужасные названия вещей.

...