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
    • Definition and Usage
    • Pattern Matching Caveats
    • Tips & Tricks
  • 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 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 / Extensible Variant
Edit

Extensible Variant

Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type even after its initial type declaration. For this, we offer extensible variant types.

Definition and Usage

ReScriptJS Output
type t = ..

type t += Other

type t +=
  | Point(float, float)
  | Line(float, float, float, float)

The .. in the type declaration above defines an extensible variant type t. The += operator is then used to add constructors to the given type.

Note: Don't forget the leading type keyword when using the += operator!

Pattern Matching Caveats

Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default _ case for every switch expression.

ReScriptJS Output
let print = v =>
  switch v {
  | Point(x, y) => Console.log2("Point", (x, y))
  | Line(ax, ay, bx, by) => Console.log2("Line", (ax, ay, bx, by))
  | Other
  | _ => Console.log("Other")
  }

Tips & Tricks

Fun fact: In ReScript, exceptions are actually extensible variants under the hood, so exception UserError(string) is equivalent to type exn += UserError(string). It's one of the very few use-case where extensible variants make sense.

We usually recommend sticking with common variants as much as possible to reap the benefits of exhaustive pattern matching.

Equality and ComparisonScoped Polymorphic Types

© 2024 The ReScript Project

Software and assets distribution powered by KeyCDN.

About
  • Community
  • ReScript Association
Find us on