Quick Links
  • -Overview
  • -Language Features
  • -JS Interop
  • -Build System
Documentation
Language Manual
Reference for all language features
ReScript & React
First class bindings for ReactJS
GenType
Seamless TypeScript integration
Reanalyze
Dead Code & Termination analysis
Exploration
Packages
Explore third party libraries and bindings
Syntax Lookup
Discover all syntax constructs
APIPlaygroundBlogCommunity
  • Playground
  • Blog
  • Twitter
  • GitHub
  • Forum
Language Manual
Overview
  • Introduction
  • Installation
  • Editor Plugins
  • Migrate to ReScript Syntax
  • Try
Language Features
  • Overview
  • Let Binding
  • Type
  • Primitive Types
  • Tuple
  • Record
  • Object
  • Variant
  • Null, Undefined and Option
  • Array & List
  • Function
  • If-Else & Loops
  • Pipe
  • Pattern Matching / Destructuring
  • Mutation
  • JSX
  • Exception
  • Lazy Values
  • Promise
  • Module
  • Import & Export
  • Reserved Keyword
JavaScript Interop
  • Embed Raw JavaScript
  • Shared Data Types
  • External (Bind to Any JS Library)
  • Bind to JS Object
    • Bind to Record-like JS Objects
    • Bind to Hash Map-like JS Object
    • Bind to a JS Object That's a Class
  • Bind to JS Function
  • Import from / Export to JS
  • Bind to Global JS Values
  • JSON
  • Use Illegal Identifier Names
  • Generate Converters & Helpers
  • Browser Support & Polyfills
  • Interop Cheatsheet
Build System
  • Build System Overview
  • Build System Configuration
  • Interop with JS Build Systems
  • Build Performance
Guides
  • Converting from JS
  • Libraries
Extra
  • Newcomer Examples
  • Project Structure
  • FAQ
Docs / Language Manual / Bind to JS Object
Edit

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

(These docs are equivalent to the old BuckleScript docs before the ReScript rebrand)

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();
External (Bind to Any JS Library)Bind to JS Function

© 2024 The ReScript Project

Software and assets distribution powered by KeyCDN.

About
  • Community
  • ReScript Association
Find us on