When working with data structures, it’s advantageous to be able to construct values that align with a specific schema effortlessly.
For this purpose, we offer default constructors for several types of schemas, including Structs, Records, filters, and brands.
Structs
Example
There are scenarios where you might want to bypass validation during instantiation.
Although not typically recommended, effect/Schema allows for this flexibility:
Records
Example
Filters
Example
Branded Types
Example
When utilizing our default constructors, it’s important to grasp the type of value they generate.
In the BrandedNumberSchema example, the return type of the constructor is number & Brand<"MyNumber">, indicating that the resulting value is a number with the added branding “MyNumber”.
This differs from the filter example where the return type is simply number.
The branding offers additional insights about the type, facilitating the identification and manipulation of your data.
Note that default constructors are “unsafe” in the sense that if the input does not conform to the schema, the constructor throws an error containing a description of what is wrong.
This is because the goal of default constructors is to provide a quick way to create compliant values (for example, for writing tests or configurations, or in any situation where it is assumed that the input passed to the constructors is valid and the opposite situation is exceptional).
To have a “safe” constructor, you can use Schema.validateEither:
Setting Default Values
When constructing objects, it’s common to want to assign default values to certain fields to simplify the creation of new instances.
The Schema.withConstructorDefault function allows you to manage the optionality of a field in your default constructor.
Example (Without Default)
Example (With Default)
In the second example, notice how the age field is now optional and defaults to 0 when not provided.
Defaults are lazily evaluated, meaning that a new instance of the default is generated every time the constructor is called:
Note how the timestamp field varies.
Default values are also “portable”, meaning that if you reuse the same property signature in another schema, the default is carried over: