This is the latest docs version
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
  • Migrate to v11
  • Editor Plugins
  • Try
Language Features
  • Overview
  • Let Binding
  • Type
  • Primitive Types
  • Tuple
  • Record
  • Object
  • Variant
  • Polymorphic Variant
  • Null, Undefined and Option
  • Array & List
  • Function
  • If-Else & Loops
  • Pipe
  • Pattern Matching / Destructuring
  • Mutation
  • JSX
  • Exception
  • Lazy Value
  • Promises
  • Async / Await
  • Tagged templates
  • Module
  • Import & Export
  • Attribute (Decorator)
  • Reserved Keywords
  • Equality and Comparison
Advanced Features
  • Extensible Variant
  • Scoped Polymorphic Types
JavaScript Interop
  • Interop Cheatsheet
  • 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
  • Inlining Constants
  • Use Illegal Identifier Names
  • Generate Converters & Helpers
  • Browser Support & Polyfills
  • Libraries & Publishing
  • TypeScript
Build System
  • Overview
  • Configuration
  • Configuration Schema
  • External Stdlib
  • Pinned Dependencies
  • Interop with JS Build Systems
  • Performance
  • Warning Numbers
Guides
  • Converting from JS
Extra
  • Newcomer Examples
  • Project Structure
  • FAQ
Docs / Language Manual / Bind to JS Object
Edit

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!

ReScriptJS Output
type person = {
  name: string,
  friends: array<string>,
  age: int,
}

@module("MySchool") external john: person = "john"

let johnName = john.name

External is documented here. @module is documented here.

If you want or need to use different field names on the ReScript and the JavaScript side, you can use the @as decorator:

ReScriptJS Output
type action = {
  @as("type") type_: string
}

let action = {type_: "ADD_USER"}

This is useful to map to JavaScript attribute names that cannot be expressed in ReScript (such as keywords).

It is also possible to map a ReScript record to a JavaScript array by passing indices to the @as decorator:

ReScriptJS Output
type t = {
  @as("0") foo: int,
  @as("1") bar: string,
}

let value = {foo: 7, bar: "baz"}

Bind Using ReScript Object

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

ReScriptJS Output
type person = {
  "name": string,
  "friends": array<string>,
  "age": int,
}

@module("MySchool") external john: person = "john"

let johnName = john["name"]

Bind Using Special Getter and Setter Attributes

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

ReScriptJS Output
type textarea
@set external setName: (textarea, string) => unit = "name"
@get external getName: textarea => string = "name"

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

ReScriptJS Output
type t
@new external create: int => t = "Int32Array"
@get_index external get: (t, int) => int = ""
@set_index external set: (t, int, int) => unit = ""

let i32arr = create(3)
i32arr->set(0, 42)
Console.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 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 new to emulate e.g. new Date():

ReScriptJS Output
type t
@new external createDate: unit => t = "Date"

let date = createDate()

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

ReScriptJS Output
type t
@new @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