0

Say I have the following Bucklescript types:

type amqp;

[@bs.val] external amqpLib: amqp = "Amqp";

[@bs.module] external amqplib : amqp = "";

class type amqpConnectionT =
  [@bs]
  {
    pub createChannel: unit => unit;
    pub close: unit => unit
  };

type amqpConnection = Js.t(amqpConnectionT);

let make = () => amqplib;

[@bs.send] external connect : (amqp, string) => Js.Promise.t(amqpConnection) = "";

let connectAmqp = (input: string, amqpClient: amqp) : Js.Promise.t(amqpConnection) => connect(amqpClient, input);

let makeConnection = (input) => make() |> connectAmqp(input, _);

and then the following code:

let start = () =>
  Amqp.makeConnection("amqp://localhost")
  |> Js.Promise.then_(connection => {
    Js.log(connection);
    connection.createChannel();
    Js.Promise.resolve(connection);
  });

start();

This fails with:

The record field createChannel can't be found.

Why? How is my type annotation incorrect?

And what is the correct way to expose member methods like this in ReasonML?

Abraham P
  • 15,029
  • 13
  • 58
  • 126

1 Answers1

2

try connection##createChannel() if it's coming from JS.

The compiler thinks that connection is a record as you're using the . accessor

glennsl
  • 28,186
  • 12
  • 57
  • 75
Boyswan
  • 224
  • 1
  • 4
  • 12
  • So what is the ## syntax? Why isn't it a record? And where is this all documented? – Abraham P Jul 07 '18 at 15:16
  • 2
    This is documented in bucklescript here https://bucklescript.github.io/docs/en/object-deprecated#accessors The above code is binding amqp in a deprecated manner. See https://bucklescript.github.io/docs/en/object for the new binding pattern. This will make using the binding much simpler. – Steven Scaffidi Jul 09 '18 at 13:51