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!
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:
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:
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:
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()
:
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:
type t
@bs.new @bs.module external book: unit => t = "Book"
let myBook = book()