The ReScript type checker is strict right up to the line where an external tells it what some JavaScript function returns. After that it just believes you. Bind getItem from localStorage as returning string and every caller gets to treat the result as a string, even though the browser hands back null for a missing key. Nothing checks it at runtime. That's the point of zero-cost bindings, and it's also where the type safety quietly stops.
The honest binding returns Nullable.t<string> and converts to option once, right where the value comes in, so the rest of the UI code matches on Some and None and can't forget the empty case. TypeScript has the same weak spot in .d.ts files. It just feels more familiar there.
What I keep going back and forth on is how much to wrap. A thin binding plus one conversion function is cheap. A hand-written module per library is safer and goes stale every time the library changes.