Skip to content

Latest commit

 

History

History
161 lines (117 loc) · 3.67 KB

object.mdx

File metadata and controls

161 lines (117 loc) · 3.67 KB
titledescriptioncanonical
Object
Interoping with JS objects in ReScript
/docs/manual/latest/object

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:

<CodeTab labels={["ReScript", "JS Output"]}>

typeperson= { "age": int, "name": string };
// Empty output

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

Creation

To create a new object:

<CodeTab labels={["ReScript", "JS Output"]}>

letme= { "age": 5, "name": "Big ReScript" }
varme={"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:

<CodeTab labels={["ReScript", "JS Output"]}>

typeperson= { "age": int }; letme= { "age": "hello!"// age is a string. No error. }
varme={"age": "hello!"};

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:

letme: person= { "age": "hello!" }

Now the type system will error properly.

Access

<CodeTab labels={["ReScript", "JS Output"]}>

letage=me["age"]
varage=me["age"];

Update

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

<CodeTab labels={["ReScript", "JS Output"]}>

typestudent= { @set"age": int, @set"name": string, } @module("MyJSFile") externalstudent1: student="student1"student1["name"] ="Mary"
varMyJSFile=require("MyJSFile");MyJSFile.student1.name="Mary";

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:

<CodeTab labels={["ReScript", "JS Output"]}>

// The type of document is just some random type 'a// that we won't bother to specify @valexternaldocument: 'a="document"// call a methoddocument["addEventListener"]("mouseup", _event=> { Js.log("clicked!") }) // get a propertyletloc=document["location"] // set a propertydocument["location"]["href"] ="rescript-lang.org"
document.addEventListener("mouseup",function(_event){console.log("clicked!");});varloc=document.location;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.

close