Skip to content

Latest commit

 

History

History
52 lines (36 loc) · 1.37 KB

bs.val.md

File metadata and controls

52 lines (36 loc) · 1.37 KB

[@bs.val]

bs.val allows you to access JS values that are available on the global scope.

For example:

[@bs.val] external setTimeout: (unit => unit, int) => float = "setTimeout";

setTimeout(() => Js.log("Hello"), 1000);

When BS and JS names match, you can use a "" shorthand:

[@bs.val] external setTimeout : (unit => unit, int) => float = "";
[@bs.val] external clearTimeout: int => unit = "";

Let's make sure that clearTimeout can only get timeoutIDs returned by setTimeout, not any int.

Abstract types to the rescue!

type timeoutID;
[@bs.val] external setTimeout: (unit => unit, int) => timeoutID = "";
[@bs.val] external clearTimeout: timeoutID => unit = "";

What if the value we want to access is on another global object, e.g. Math.floor, Date.now, or even location.origin.length?

By adding bs.scope we can access "deep" values. For example:

[@bs.scope "Math"] [@bs.val] external floor: float => int = "";
[@bs.scope "Date"] [@bs.val] external now: unit => int = "";
[@bs.scope ("location", "origin")] [@bs.val] external originLength: string = "length";

let low = floor(3.4);
let timestamp = now();
Js.log(originLength);

compiles to:

var low = Math.floor(3.4);
var timestamp = Date.now();
console.log(location.origin.length);

Note: The order of bs.scope and bs.val doesn't matter.