Hello, I’m working on bindings to a JS library and it’s going well and compiling to what I would type in JS. I have an object method that takes a callback that I have typed as type callback = (. Js.nullable<Js.Exn.t>, Js.nullable<t>) => unit
, which I adapted a bit from another answer on here. I’m going for an uncurried function that takes an error and the data; both could presumably (mutually exclusively) be undefined or null, or their respective value. Now I need to use it to send a callback function to the JS side. How should I test for the presence of err
? I see there is a isNullable
function that returns true if the value is null/undefined and a test
(no description) that I guess returns false on null/undefined; should I switch
on that result? Something else? Thank you!
You can use Js.Nullable | ReScript API to convert it to an option value, then switch on it like a normal option e.g. Some
/None
.
EDIT: if you use this style a lot you can write a little wrapper to convert the Node callback style into a more type-safe result style:
let nodeback = (f) => (. err, result) =>
switch (Js.Nullable.toOption(err), Js.Nullable.toOption(result)) {
| (Some(err), _) => f(Error(err))
| (_, Some(result)) => f(Ok(result))
// Throw if APIs break nodeback 'guarantee':
| _ => invalid_arg("Nodeback arguments invalid")
}
Then,
fetchData(nodeback(result =>
switch result {
| Ok(value) => ...
| Error(ex) => ...
}))
Ok thank you. Another parameter of this object method is array of myType
, but null
can also be passed in. I typed it in my external for the method as Js.null<array<myType>>
because the API docs say “nullable, value of this type can be either null or 'a”, which sounds like what I want. However, when I call the method and pass in an array of myType
like [myValue]
, it won’t compile. It says “This has type: array<'a> Somewhere wanted: Js.null<array<myType>>
”. So I am misunderstanding something. I’m not sure I will even need to pass in nulls, I just wanted to create the most robust and flexible binding to the method. Is that the right approach? How can I fix?
I changed the type in my external to Js.Nullable.t<array<myType>>
and then at the call site I used Js.Nullable.return([myValue])
and that is compiling, is that right? I haven’t tried it in the browser yet though.
Yes, that’s exactly what I was going to suggest.
Awesome, thank you so much!