处理 Js.Nullable 的正确方法是什么?

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

我正在尝试执行以下操作:

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|]);

当然,我收到以下投诉:

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

所以我用string_of_int:

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

但是我后来运行陷入了问题:

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

使用 switch 的正确方法是正确的还是有其他方法?

您可以使用 Js.Nullable.bind:

更改 Js.Nullable.t 的 "inner" 类型
let str_of_int_result: Js.Nullable.t(string) =
  Js.Nullable.bind(int_result, (. n) => string_iof_int(n));

或者,您可以将 Js.Nullable.t 转换为 option,在其上进行模式匹配,然后可选择将其再次包裹在 Js.Nullable.t 中:

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
  };

为了比较,这些是等价的。如果你想让它保持 Js.Nullable.t,你通常会想使用第一种方法,如果不想,则使用第二种方法。

当使用 ReasonReact Ref 访问 DOM 节点时,我使用以下方法将 DOM 节点作为对象(又名 Js.t<'a>)访问。

let nodeRef = React.useRef(Js.Nullable.null)

...

switch Js.Nullable.toOption(nodeRef.current) {
| None => ()
| Some(node) => {
    let node = ReactDOMRe.domElementToObj(node)
    node["scrollTop"] = node["scrollHeight"]
  }
}

...

<main ref={ReactDOM.Ref.domRef(nodeRef)}>