Bind to Global JS Values
First, make sure the value you'd like to model doesn't already exist in our provided API.
Some JS values, like
setTimeout, live in the global scope. You can bind to them like so:
(We already provide
clearTimeout and others in the Js.Global module).
setTimeout methods and the corresponding
external's type annotation specifies that
Takes a function that accepts
unit(which on the JS side turns into a function that accepts nothing and returns nothing aka
and an integer that specifies the duration before calling said function,
returns a number that is the timeout's ID. This number might be big, so we're modeling it as a float rather than the 32-bit int.
The above isn't ideal. See how
setTimeout returns a
clearTimeout accepts one. There's no guarantee that you're passing the float created by
clearTimeout! For all we know, someone might pass it
Math.random() into the latter.
We're in a language with a great type system now! Let's leverage a popular feature to solve this problem: abstract types.
timerId is a type that can only be created by
setTimeout! Now we've guaranteed that
clearTimeout will be passed a valid ID. Whether it's a number under the hood is now a mere implementation detail.
externals are inlined, we end up with JS output as readable as hand-written JS.
If you want to bind to a value inside a global module, e.g.
Math.random, attach a
scope to your
you can bind to an arbitrarily deep object by passing a tuple to
This binds to
Global values like
__DEV__ don't always exist; you can't even model them as an
option, since the mere act of referring to them in ReScript (then compiled into JS) would trigger the usual
Uncaught ReferenceError: __filename is not defined error in e.g. the browser environment.
For these troublesome global values, ReScript provides a special approach:
That first line's
typeof check won't trigger a JS ReferenceError.