nullablereasonbucklescript

What's the proper way to deal with Js.Nullable?


I'm trying to do something like the following:

let str_result: Js.Nullable.t(string) = Js.Nullable.return("something");
let int_result: Js.Nullable.t(int) = Js.Nullable.fromOption(Some(5));
Js.log([|str_result, int_result|]);

But of course, I get the following complaint:

Error: This expression has type Js.Nullable.t(int) = Js.nullable(int)
       but an expression was expected of type
         Js.Nullable.t(string) = Js.nullable(string)
       Type int is not compatible with type string

So I use string_of_int:

Js.log([|str_result, string_of_int|]);

But I then run into the problem of:

This has type:
  Js.Nullable.t(int) (defined as Js.nullable(int))
But somewhere wanted:
  int

Is the proper way to use a switch or is there another way to do this?


Solution

  • You can change the "inner" type of a Js.Nullable.t using Js.Nullable.bind:

    let str_of_int_result: Js.Nullable.t(string) =
      Js.Nullable.bind(int_result, (. n) => string_iof_int(n));
    

    Alternatively, you can turn a Js.Nullable.t into an option, pattern match on it, and then optionally wrap it up in a Js.Nullable.t again:

    let str_of_int_result: Js.Nullable.t(string) =
      switch (Js.Nullable.toOption(int_result)) {
      | Some(n) => Js.Nullable.return(string_of_int(n)))
      | None    => Js.Nullable.null
      };
    

    These are equivalent, for the sake of comparison. You'll usually want to use the first method if you want to keep it a Js.Nullable.t, and the second method if you don't.