OCaml itself doesn't have the notion of
undefined. This is a great thing, as it wipes out an entire category of bugs.
BuckleScript provides access to
To create a JS
null, use the value
Js.Nullable.null. To create a Js
If you're receiving, for example, a JS string that can also be null, type it as:
let theJsValue: string Js.Nullable.t = /* the value you've gotten here */
let theJsValue: Js.Nullable.t(string) = /* the value you've gotten here */
To create a nullable string, do:
let nullableString: string Js.Nullable.t = Js.Nullable.return "hello"
let nullableString: Js.Nullable.t(string) = Js.Nullable.return("hello");
return part "wraps" a string into a nullable string, to make the type system understand and track the fact that, as you pass this value around, it's not just a string, but a string that can be
undefined. Tada! No more nullable bugs!
This is the idiomatic way of working with the concept of "no value" in BuckleScript/OCaml/Reason. The Reason docs on variants describes option in more detail.
Js.Nullable.fromOption converts from a
Js.Nullable.toOption does the opposite.
Option helper module is here.
Tips & Tricks
In an external, you can directly convert a
Js.Nullable.t into an
type element external getElementById : string -> element option = "getElementById" [@@bs.val][@@bs.scope "document"][@@bs.return nullable]
type element; [ .val] [ .return nullable] [ .scope "document"] external getElementById : string => option(element) = "getElementById";
When you use
getElementById, it'll implicitly convert the JS nullable string into an option. Saves you an explicit conversion through
OCaml/BuckleScript option is a "boxed" value. Under BuckleScript, a
None is compiled into
0 and a
Some foo is compiled into
[foo]. The above
bs.return nullable smartly removes such boxing overhead when the returned value is destructed in the same routine.