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
  • X
  • Bluesky
  • GitHub
  • Forum
Language Manual
Overview
  • Introduction
  • Installation
  • Migrate to v11
  • Editor Plugins
  • Try
Language Features
  • Overview
  • Let Binding
  • Type
  • Primitive Types
  • Tuple
  • Record
  • Object
    • Type Declaration
    • Creation
    • Access
    • Update
    • Combine Types
    • Tips & Tricks
  • 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
  • Module Functions
JavaScript Interop
  • Interop Cheatsheet
  • Embed Raw JavaScript
  • Shared Data Types
  • External (Bind to Any JS Library)
  • Bind to JS Object
  • 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 / Object
Edit

Object

ReScript objects are like records, but:

  • No type declaration needed.

  • Structural and more polymorphic, unlike records.

  • Doesn't support updates unless the object comes from the JS side.

  • Doesn't support pattern matching.

Although ReScript records compile to clean JavaScript objects, ReScript objects are a better candidate for emulating/binding to JS objects, as you'll see.

Type Declaration

Optional, unlike for records. The type of an object is inferred from the value, so you never really need to write down its type definition. Nevertheless, here's its type declaration syntax:

ReScriptJS Output
type person = {
  "age": int,
  "name": string
};

Visually similar to record type's syntax, with the field names quoted.

Creation

To create a new object:

ReScriptJS Output
let me = {
  "age": 5,
  "name": "Big ReScript"
}

Note: as said above, unlike for record, this me value does not try to find a conforming type declaration with the field "age" and "name"; rather, the type of me is inferred as {"age": int, "name": string}. This is convenient, but also means this code passes type checking without errors:

ReScriptJS Output
type person = {
  "age": int
};

let me = {
  "age": "hello!" // age is a string. No error.
}

Since the type checker doesn't try to match me with the type person. If you ever want to force an object value to be of a predeclared object type, just annotate the value:

RES
let me: person = { "age": "hello!" }

Now the type system will error properly.

Access

ReScriptJS Output
let age = me["age"]

Update

Disallowed unless the object is a binding that comes from the JavaScript side. In that case, use =

ReScriptJS Output
type student = {
  @set "age": int,
  @set "name": string,
}
@module("MyJSFile") external student1: student = "student1"

student1["name"] = "Mary"

Combine Types

You can spread one object type definition into another using ...:

ReScriptJS Output
type point2d = {
  "x": float,
  "y": float,
}
type point3d = {
  ...point2d,
  "z": float,
}

let myPoint: point3d = {
  "x": 1.0,
  "y": 2.0,
  "z": 3.0,
}

This only works with object types, not object values!

Tips & Tricks

Since objects don't require type declarations, and since ReScript infers all the types for you, you get to very quickly and easily (and dangerously) bind to any JavaScript API. Check the JS output tab:

ReScriptJS Output
// The type of document is just some random type 'a
// that we won't bother to specify
@val external document: 'a = "document"

// call a method
document["addEventListener"]("mouseup", _event => {
  Console.log("clicked!")
})

// get a property
let loc = document["location"]

// set a property
document["location"]["href"] = "rescript-lang.org"

The external feature and the usage of this trick are also documented in the external section later. It's an excellent way to start writing some ReScript code without worrying about whether bindings to a particular library exists.

RecordVariant

© 2024 The ReScript Project

Software and assets distribution powered by KeyCDN.

About
  • Community
  • ReScript Association
Find us on