Docs / Language Manual / BindToJsObject

You are currently looking at the v8.0.0 docs (Reason v3.6 syntax edition). You can find the latest manual page here.

Bind to JS Object

JavaScript objects are a combination of several use-cases:

  • As a "record" or "struct" in other languages (like ReScript and C).

  • As a hash map.

  • As a class.

  • As a module to import/export.

ReScript cleanly separates the binding methods for JS object based on these 4 use-cases. This page documents the first three. Binding to JS module objects is described in the Import from/Export to JS section.

Bind to Record-like JS Objects

Bind Using ReScript Record

If your JavaScript object has fixed fields, then it's conceptually like a ReScript record. Since a ReScript record compiles to a clean JavaScript object, you can definitely type a JS object as a ReScript record!

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type person = {
  name: string,
  friends: array(string),
  age: int,
};

[@bs.module "MySchool"] external john: person = "john";

let johnName = john.name;

External is documented here. @bs.module is documented here.

Bind Using ReScript Object

Alternatively, you can use ReScript object to model a JS object too:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type person = {
  .
  "name": string,
  "friends": array(string),
  "age": int,
};

[@bs.module "MySchool"] external john: person = "john";

let johnName = john##name;

Bind Using Special @bs Getters & Setters

Alternatively, you can use bs.get and bs.set to bind to individual fields of a JS object:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type textarea;
[@bs.set] external setName: (textarea, string) => unit = "name";
[@bs.get] external getName: textarea => string = "name";

You can also use bs.get_index and bs.set_index to access a dynamic property or an index:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type t;
[@bs.new] external create: int => t = "Int32Array";
[@bs.get_index] external get: (t, int) => int = "";
[@bs.set_index] external set: (t, int, int) => unit = "";

let i32arr = create(3);
i32arr->set(0, 42);
Js.log(i32arr->get(0));

Bind to Hash Map-like JS Object

If your JavaScript object:

  • might or might not add/remove keys

  • contains only values that are of the same type

Then it's not really an object, it's a hash map. Use Js.Dict, which contains operations like get, set, etc. and cleanly compiles to a JavaScript object still.

Bind to a JS Object That's a Class

Use bs.new to emulate e.g. new Date():

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type t;
[@bs.new] external createDate: unit => t = "Date";

let date = createDate();

You can chain bs.new and bs.module if the JS module you're importing is itself a class:

Reason (Old Syntax)ML (Older Syntax)JS Output
 
type t;
[@bs.new] [@bs.module] external book: unit => t = "Book";
let myBook = book();