Skip to content

Basic Usage

The Schema module provides built-in schemas for common primitive types.

SchemaEquivalent TypeScript Type
Schema.Stringstring
Schema.Numbernumber
Schema.Booleanboolean
Schema.BigIntFromSelfBigInt
Schema.SymbolFromSelfsymbol
Schema.Objectobject
Schema.Undefinedundefined
Schema.Voidvoid
Schema.Anyany
Schema.Unknownunknown
Schema.Nevernever

Example (Using a Primitive Schema)

import {
import Schema
Schema
} from "effect"
const
const schema: typeof Schema.String
schema
=
import Schema
Schema
.
class String
export String

@since3.10.0

String
// Infers the type as string
//
// ┌─── string
// ▼
type
type Type = string
Type
= typeof
const schema: typeof Schema.String
schema
.
Schema<string, string, never>.Type: string
Type
// Attempt to decode a null value, which will throw a parse error
import Schema
Schema
.
decodeUnknownSync<string, string>(schema: Schema.Schema<string, string, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => string
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const schema: typeof Schema.String
schema
)(null)
/*
throws:
ParseError: Expected string, actual null
*/

To make it easier to work with schemas, built-in schemas are exposed with shorter, opaque types when possible.

The Schema.asSchema function allows you to view any schema as Schema<Type, Encoded, Context>.

Example (Expanding a Schema with asSchema)

For example, while Schema.String is defined as a class with a type of typeof Schema.String, using Schema.asSchema provides the schema in its extended form as Schema<string, string, never>.

import {
import Schema
Schema
} from "effect"
// ┌─── typeof Schema.String
// ▼
const
const schema: typeof Schema.String
schema
=
import Schema
Schema
.
class String
export String

@since3.10.0

String
// ┌─── Schema<string, string, never>
// ▼
const
const nomalized: Schema.Schema<string, string, never>
nomalized
=
import Schema
Schema
.
const asSchema: <typeof Schema.String>(schema: typeof Schema.String) => Schema.Schema<string, string, never>

@since3.10.0

asSchema
(
const schema: typeof Schema.String
schema
)

You can create a schema for unique symbols using Schema.UniqueSymbolFromSelf.

Example (Creating a Schema for a Unique Symbol)

import {
import Schema
Schema
} from "effect"
const
const mySymbol: typeof mySymbol
mySymbol
=
var Symbol: SymbolConstructor
Symbol
.
SymbolConstructor.for(key: string): symbol

Returns a Symbol object from the global symbol registry matching the given key if found. Otherwise, returns a new symbol with this key.

@paramkey key to search for.

for
("mySymbol")
const
const schema: Schema.SchemaClass<typeof mySymbol, typeof mySymbol, never>
schema
=
import Schema
Schema
.
const UniqueSymbolFromSelf: <typeof mySymbol>(symbol: typeof mySymbol) => Schema.SchemaClass<typeof mySymbol, typeof mySymbol, never>

@since3.10.0

UniqueSymbolFromSelf
(
const mySymbol: typeof mySymbol
mySymbol
)
// ┌─── typeof mySymbol
// ▼
type
type Type = typeof mySymbol
Type
= typeof
const schema: Schema.SchemaClass<typeof mySymbol, typeof mySymbol, never>
schema
.
Schema<typeof mySymbol, typeof mySymbol, never>.Type: typeof mySymbol
Type
import Schema
Schema
.
decodeUnknownSync<typeof mySymbol, typeof mySymbol>(schema: Schema.Schema<typeof mySymbol, typeof mySymbol, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => typeof mySymbol
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const schema: Schema.SchemaClass<typeof mySymbol, typeof mySymbol, never>
schema
)(null)
/*
throws:
ParseError: Expected Symbol(mySymbol), actual null
*/

Literal schemas represent a literal type. You can use them to specify exact values that a type must have.

Literals can be of the following types:

  • string
  • number
  • boolean
  • null
  • bigint

Example (Defining Literal Schemas)

import {
import Schema
Schema
} from "effect"
// Define various literal schemas
import Schema
Schema
.
class Null

@since3.10.0

Null
// Same as S.Literal(null)
import Schema
Schema
.
function Literal<["a"]>(literals_0: "a"): Schema.Literal<["a"]> (+2 overloads)

@since3.10.0

Literal
("a") // string literal
import Schema
Schema
.
function Literal<[1]>(literals_0: 1): Schema.Literal<[1]> (+2 overloads)

@since3.10.0

Literal
(1) // number literal
import Schema
Schema
.
function Literal<[true]>(literals_0: true): Schema.Literal<[true]> (+2 overloads)

@since3.10.0

Literal
(true) // boolean literal
import Schema
Schema
.
function Literal<[2n]>(literals_0: 2n): Schema.Literal<[2n]> (+2 overloads)

@since3.10.0

Literal
(2n) // BigInt literal

Example (Defining a Literal Schema for "a")

import {
import Schema
Schema
} from "effect"
// ┌─── Literal<["a"]>
// ▼
const
const schema: Schema.Literal<["a"]>
schema
=
import Schema
Schema
.
function Literal<["a"]>(literals_0: "a"): Schema.Literal<["a"]> (+2 overloads)

@since3.10.0

Literal
("a")
// ┌─── "a"
// ▼
type
type Type = "a"
Type
= typeof
const schema: Schema.Literal<["a"]>
schema
.
Schema<"a", "a", never>.Type: "a"
Type
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a", "a">(schema: Schema.Schema<"a", "a", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const schema: Schema.Literal<["a"]>
schema
)("a"))
// Output: "a"
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a", "a">(schema: Schema.Schema<"a", "a", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const schema: Schema.Literal<["a"]>
schema
)("b"))
/*
throws:
ParseError: Expected "a", actual "b"
*/

You can create a union of multiple literals by passing them as arguments to the Schema.Literal constructor:

Example (Defining a Union of Literals)

import {
import Schema
Schema
} from "effect"
// ┌─── Literal<["a", "b", "c"]>
// ▼
const
const schema: Schema.Literal<["a", "b", "c"]>
schema
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c")
// ┌─── "a" | "b" | "c"
// ▼
type
type Type = "a" | "b" | "c"
Type
= typeof
const schema: Schema.Literal<["a", "b", "c"]>
schema
.
Schema<"a" | "b" | "c", "a" | "b" | "c", never>.Type: "a" | "b" | "c"
Type
import Schema
Schema
.
decodeUnknownSync<"a" | "b" | "c", "a" | "b" | "c">(schema: Schema.Schema<"a" | "b" | "c", "a" | "b" | "c", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a" | ... 1 more ... | "c"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const schema: Schema.Literal<["a", "b", "c"]>
schema
)(null)
/*
throws:
ParseError: "a" | "b" | "c"
├─ Expected "a", actual null
├─ Expected "b", actual null
└─ Expected "c", actual null
*/

If you want to set a custom error message for the entire union of literals, you can use the override: true option (see Custom Error Messages for more details) to specify a unified message.

Example (Adding a Custom Message to a Union of Literals)

import {
import Schema
Schema
} from "effect"
// Schema with individual messages for each literal
const
const individualMessages: Schema.Literal<["a", "b", "c"]>
individualMessages
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a" | "b" | "c", "a" | "b" | "c">(schema: Schema.Schema<"a" | "b" | "c", "a" | "b" | "c", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a" | ... 1 more ... | "c"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const individualMessages: Schema.Literal<["a", "b", "c"]>
individualMessages
)(null))
/*
throws:
ParseError: "a" | "b" | "c"
├─ Expected "a", actual null
├─ Expected "b", actual null
└─ Expected "c", actual null
*/
// Schema with a unified custom message for all literals
const
const unifiedMessage: Schema.Literal<["a", "b", "c"]>
unifiedMessage
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c").
Annotable<Literal<["a", "b", "c"]>, "a" | "b" | "c", "a" | "b" | "c", never>.annotations(annotations: Schema.Annotations.GenericSchema<"a" | "b" | "c">): Schema.Literal<["a", "b", "c"]>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Schema<"a" | "b" | "c", readonly []>.message?: MessageAnnotation
message
: () => ({
message: string | Effect<string, never, never>
message
: "Not a valid code",
override: boolean
override
: true })
})
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a" | "b" | "c", "a" | "b" | "c">(schema: Schema.Schema<"a" | "b" | "c", "a" | "b" | "c", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a" | ... 1 more ... | "c"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const unifiedMessage: Schema.Literal<["a", "b", "c"]>
unifiedMessage
)(null))
/*
throws:
ParseError: Not a valid code
*/

You can access the literals defined in a literal schema using the literals property:

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.Literal<["a", "b", "c"]>
schema
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c")
// ┌─── readonly ["a", "b", "c"]
// ▼
const
const literals: readonly ["a", "b", "c"]
literals
=
const schema: Schema.Literal<["a", "b", "c"]>
schema
.
Literal<["a", "b", "c"]>.literals: readonly ["a", "b", "c"]
literals

You can use Schema.pickLiteral with a literal schema to narrow down its possible values.

Example (Using pickLiteral to Narrow Values)

import {
import Schema
Schema
} from "effect"
// Create a schema for a subset of literals ("a" and "b") from a larger set
//
// ┌─── Literal<["a", "b"]>
// ▼
const
const schema: Schema.Literal<["a", "b"]>
schema
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c").
Pipeable.pipe<Schema.Literal<["a", "b", "c"]>, Schema.Literal<["a", "b"]>>(this: Schema.Literal<...>, ab: (_: Schema.Literal<["a", "b", "c"]>) => Schema.Literal<["a", "b"]>): Schema.Literal<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const pickLiteral: <"a" | "b" | "c", ["a", "b"]>(literals_0: "a", literals_1: "b") => <I, R>(_schema: Schema.Schema<"a" | "b" | "c", I, R>) => Schema.Literal<["a", "b"]>

Creates a new Schema from a literal schema.

@example

import * as Schema from "effect/Schema"
import { Either } from "effect"
const schema = Schema.Literal("a", "b", "c").pipe(Schema.pickLiteral("a", "b"))
assert.deepStrictEqual(Schema.decodeSync(schema)("a"), "a")
assert.deepStrictEqual(Schema.decodeSync(schema)("b"), "b")
assert.strictEqual(Either.isLeft(Schema.decodeUnknownEither(schema)("c")), true)

@since3.10.0

pickLiteral
("a", "b")
)

Sometimes, you may need to reuse a literal schema in other parts of your code. Below is an example demonstrating how to do this:

Example (Creating a Subtype from a Literal Schema)

import {
import Schema
Schema
} from "effect"
// Define the base set of fruit categories
const
const FruitCategory: Schema.Literal<["sweet", "citrus", "tropical"]>
FruitCategory
=
import Schema
Schema
.
function Literal<["sweet", "citrus", "tropical"]>(literals_0: "sweet", literals_1: "citrus", literals_2: "tropical"): Schema.Literal<["sweet", "citrus", "tropical"]> (+2 overloads)

@since3.10.0

Literal
("sweet", "citrus", "tropical")
// Define a general Fruit schema with the base category set
const
const Fruit: Schema.Struct<{
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus", "tropical"]>;
}>
Fruit
=
import Schema
Schema
.
function Struct<{
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus", "tropical"]>;
}>(fields: {
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus", "tropical"]>;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.Number
id
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
category: Schema.Literal<["sweet", "citrus", "tropical"]>
category
:
const FruitCategory: Schema.Literal<["sweet", "citrus", "tropical"]>
FruitCategory
})
// Define a specific Fruit schema for only "sweet" and "citrus" categories
const
const SweetAndCitrusFruit: Schema.Struct<{
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus"]>;
}>
SweetAndCitrusFruit
=
import Schema
Schema
.
function Struct<{
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus"]>;
}>(fields: {
id: typeof Schema.Number;
category: Schema.Literal<["sweet", "citrus"]>;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.Number
id
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
category: Schema.Literal<["sweet", "citrus"]>
category
:
const FruitCategory: Schema.Literal<["sweet", "citrus", "tropical"]>
FruitCategory
.
Pipeable.pipe<Schema.Literal<["sweet", "citrus", "tropical"]>, Schema.Literal<["sweet", "citrus"]>>(this: Schema.Literal<...>, ab: (_: Schema.Literal<["sweet", "citrus", "tropical"]>) => Schema.Literal<...>): Schema.Literal<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const pickLiteral: <"sweet" | "citrus" | "tropical", ["sweet", "citrus"]>(literals_0: "sweet", literals_1: "citrus") => <I, R>(_schema: Schema.Schema<"sweet" | "citrus" | "tropical", I, R>) => Schema.Literal<...>

Creates a new Schema from a literal schema.

@example

import * as Schema from "effect/Schema"
import { Either } from "effect"
const schema = Schema.Literal("a", "b", "c").pipe(Schema.pickLiteral("a", "b"))
assert.deepStrictEqual(Schema.decodeSync(schema)("a"), "a")
assert.deepStrictEqual(Schema.decodeSync(schema)("b"), "b")
assert.strictEqual(Either.isLeft(Schema.decodeUnknownEither(schema)("c")), true)

@since3.10.0

pickLiteral
("sweet", "citrus"))
})

In this example, FruitCategory serves as the source of truth for the different fruit categories. We reuse it to create a subtype of Fruit called SweetAndCitrusFruit, ensuring that only the specified categories ("sweet" and "citrus") are allowed. This approach helps maintain consistency throughout your code and provides type safety if the category definition changes.

In TypeScript, template literals types allow you to embed expressions within string literals. The Schema.TemplateLiteral constructor allows you to create a schema for these template literal types.

Example (Defining Template Literals)

import {
import Schema
Schema
} from "effect"
// This creates a schema for: `a${string}`
//
// ┌─── TemplateLiteral<`a${string}`>
// ▼
const
const schema1: Schema.TemplateLiteral<`a${string}`>
schema1
=
import Schema
Schema
.
const TemplateLiteral: <["a", typeof Schema.String]>(head: "a", tail_0: typeof Schema.String) => Schema.TemplateLiteral<`a${string}`>

@since3.10.0

TemplateLiteral
("a",
import Schema
Schema
.
class String
export String

@since3.10.0

String
)
// This creates a schema for:
// `https://${string}.com` | `https://${string}.net`
const
const schema2: Schema.TemplateLiteral<`https://${string}.com` | `https://${string}.net`>
schema2
=
import Schema
Schema
.
const TemplateLiteral: <["https://", typeof Schema.String, ".", Schema.Literal<["com", "net"]>]>(head: "https://", tail_0: typeof Schema.String, tail_1: ".", tail_2: Schema.Literal<["com", "net"]>) => Schema.TemplateLiteral<...>

@since3.10.0

TemplateLiteral
(
"https://",
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
".",
import Schema
Schema
.
function Literal<["com", "net"]>(literals_0: "com", literals_1: "net"): Schema.Literal<["com", "net"]> (+2 overloads)

@since3.10.0

Literal
("com", "net")
)

Example (From template literals types Documentation)

Let’s look at a more complex example. Suppose you have two sets of locale IDs for emails and footers. You can use the Schema.TemplateLiteral constructor to create a schema that combines these IDs:

import {
import Schema
Schema
} from "effect"
const
const EmailLocaleIDs: Schema.Literal<["welcome_email", "email_heading"]>
EmailLocaleIDs
=
import Schema
Schema
.
function Literal<["welcome_email", "email_heading"]>(literals_0: "welcome_email", literals_1: "email_heading"): Schema.Literal<["welcome_email", "email_heading"]> (+2 overloads)

@since3.10.0

Literal
("welcome_email", "email_heading")
const
const FooterLocaleIDs: Schema.Literal<["footer_title", "footer_sendoff"]>
FooterLocaleIDs
=
import Schema
Schema
.
function Literal<["footer_title", "footer_sendoff"]>(literals_0: "footer_title", literals_1: "footer_sendoff"): Schema.Literal<["footer_title", "footer_sendoff"]> (+2 overloads)

@since3.10.0

Literal
("footer_title", "footer_sendoff")
// This creates a schema for:
// "welcome_email_id" | "email_heading_id" |
// "footer_title_id" | "footer_sendoff_id"
const
const schema: Schema.TemplateLiteral<"welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id">
schema
=
import Schema
Schema
.
const TemplateLiteral: <[Schema.Union<[Schema.Literal<["welcome_email", "email_heading"]>, Schema.Literal<["footer_title", "footer_sendoff"]>]>, "_id"]>(head: Schema.Union<[Schema.Literal<["welcome_email", "email_heading"]>, Schema.Literal<...>]>, tail_0: "_id") => Schema.TemplateLiteral<...>

@since3.10.0

TemplateLiteral
(
import Schema
Schema
.
function Union<[Schema.Literal<["welcome_email", "email_heading"]>, Schema.Literal<["footer_title", "footer_sendoff"]>]>(members_0: Schema.Literal<["welcome_email", "email_heading"]>, members_1: Schema.Literal<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
const EmailLocaleIDs: Schema.Literal<["welcome_email", "email_heading"]>
EmailLocaleIDs
,
const FooterLocaleIDs: Schema.Literal<["footer_title", "footer_sendoff"]>
FooterLocaleIDs
),
"_id"
)

The Schema.TemplateLiteral constructor supports the following types of spans:

  • Schema.String
  • Schema.Number
  • Literals: string | number | boolean | null | bigint. These can be either wrapped by Schema.Literal or used directly
  • Unions of the above types
  • Brands of the above types

Example (Using a Branded String in a Template Literal)

import {
import Schema
Schema
} from "effect"
// Create a branded string schema for an authorization token
const
const AuthorizationToken: Schema.brand<typeof Schema.String, "AuthorizationToken">
AuthorizationToken
=
import Schema
Schema
.
class String
export String

@since3.10.0

String
.
Pipeable.pipe<typeof Schema.String, Schema.brand<typeof Schema.String, "AuthorizationToken">>(this: typeof Schema.String, ab: (_: typeof Schema.String) => Schema.brand<typeof Schema.String, "AuthorizationToken">): Schema.brand<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const brand: <typeof Schema.String, "AuthorizationToken">(brand: "AuthorizationToken", annotations?: Schema.Annotations.Schema<string & Brand<"AuthorizationToken">, readonly []> | undefined) => (self: typeof Schema.String) => Schema.brand<...>

Returns a nominal branded schema by applying a brand to a given schema.

Schema<A> + B -> Schema<A & Brand<B>>

@paramself - The input schema to be combined with the brand.

@parambrand - The brand to apply.

@example

import * as Schema from "effect/Schema"
const Int = Schema.Number.pipe(Schema.int(), Schema.brand("Int"))
type Int = Schema.Schema.Type<typeof Int> // number & Brand<"Int">

@since3.10.0

brand
("AuthorizationToken")
)
// This creates a schema for:
// `Bearer ${string & Brand<"AuthorizationToken">}`
const
const schema: Schema.TemplateLiteral<`Bearer ${string & Brand<"AuthorizationToken">}`>
schema
=
import Schema
Schema
.
const TemplateLiteral: <["Bearer ", Schema.brand<typeof Schema.String, "AuthorizationToken">]>(head: "Bearer ", tail_0: Schema.brand<typeof Schema.String, "AuthorizationToken">) => Schema.TemplateLiteral<...>

@since3.10.0

TemplateLiteral
("Bearer ",
const AuthorizationToken: Schema.brand<typeof Schema.String, "AuthorizationToken">
AuthorizationToken
)

The Schema.TemplateLiteral constructor, while useful as a simple validator, only verifies that an input conforms to a specific string pattern by converting template literal definitions into regular expressions. Similarly, Schema.pattern employs regular expressions directly for the same purpose. Post-validation, both methods require additional manual parsing to convert the validated string into a usable data format.

To address these limitations and eliminate the need for manual post-validation parsing, the Schema.TemplateLiteralParser API has been developed. It not only validates the input format but also automatically parses it into a more structured and type-safe output, specifically into a tuple format.

The Schema.TemplateLiteralParser constructor supports the same types of spans as Schema.TemplateLiteral.

Example (Using TemplateLiteralParser for Parsing and Encoding)

import {
import Schema
Schema
} from "effect"
// ┌─── Schema<readonly [number, "a", string], `${string}a${string}`>
// ▼
const
const schema: Schema.TemplateLiteralParser<[typeof Schema.NumberFromString, "a", typeof Schema.NonEmptyString]>
schema
=
import Schema
Schema
.
const TemplateLiteralParser: <[typeof Schema.NumberFromString, "a", typeof Schema.NonEmptyString]>(params_0: typeof Schema.NumberFromString, params_1: "a", params_2: typeof Schema.NonEmptyString) => Schema.TemplateLiteralParser<...>

@since3.10.0

TemplateLiteralParser
(
import Schema
Schema
.
class NumberFromString

This schema transforms a string into a number by parsing the string using the parse function of the effect/Number module.

It returns an error if the value can't be converted (for example when non-numeric characters are provided).

The following special string values are supported: "NaN", "Infinity", "-Infinity".

@since3.10.0

NumberFromString
,
"a",
import Schema
Schema
.
class NonEmptyString

@since3.10.0

NonEmptyString
)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeSync<readonly [number, "a", string], `${string}a${string}`>(schema: Schema.Schema<readonly [number, "a", string], `${string}a${string}`, never>, options?: ParseOptions): (i: `${string}a${string}`, overrideOptions?: ParseOptions) => readonly [...]
export decodeSync

@since3.10.0

decodeSync
(
const schema: Schema.TemplateLiteralParser<[typeof Schema.NumberFromString, "a", typeof Schema.NonEmptyString]>
schema
)("100afoo"))
// Output: [ 100, 'a', 'foo' ]
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
encodeSync<readonly [number, "a", string], `${string}a${string}`>(schema: Schema.Schema<readonly [number, "a", string], `${string}a${string}`, never>, options?: ParseOptions): (a: readonly [...], overrideOptions?: ParseOptions) => `${string}a${string}`
export encodeSync

@since3.10.0

encodeSync
(
const schema: Schema.TemplateLiteralParser<[typeof Schema.NumberFromString, "a", typeof Schema.NonEmptyString]>
schema
)([100, "a", "foo"]))
// Output: '100afoo'

The Schema module provides support for native TypeScript enums. You can define a schema for an enum using Schema.Enums, allowing you to validate values that belong to the enum.

Example (Defining a Schema for an Enum)

import {
import Schema
Schema
} from "effect"
enum
enum Fruits
Fruits
{
function (enum member) Fruits.Apple = 0
Apple
,
function (enum member) Fruits.Banana = 1
Banana
}
// ┌─── Enums<typeof Fruits>
// ▼
const
const schema: Schema.Enums<typeof Fruits>
schema
=
import Schema
Schema
.
const Enums: <typeof Fruits>(enums: typeof Fruits) => Schema.Enums<typeof Fruits>

@since3.10.0

Enums
(
enum Fruits
Fruits
)
//
// ┌─── Fruits
// ▼
type
type Type = Fruits
Type
= typeof
const schema: Schema.Enums<typeof Fruits>
schema
.
Schema<Fruits, Fruits, never>.Type: Fruits
Type

Enums are accessible through the enums property of the schema. You can use this property to retrieve individual members or the entire set of enum values.

import {
import Schema
Schema
} from "effect"
enum
enum Fruits
Fruits
{
function (enum member) Fruits.Apple = 0
Apple
,
function (enum member) Fruits.Banana = 1
Banana
}
const
const schema: Schema.Enums<typeof Fruits>
schema
=
import Schema
Schema
.
const Enums: <typeof Fruits>(enums: typeof Fruits) => Schema.Enums<typeof Fruits>

@since3.10.0

Enums
(
enum Fruits
Fruits
)
const schema: Schema.Enums<typeof Fruits>
schema
.
Enums<typeof Fruits>.enums: typeof Fruits
enums
// Returns all enum members
const schema: Schema.Enums<typeof Fruits>
schema
.
Enums<typeof Fruits>.enums: typeof Fruits
enums
.
function (enum member) Fruits.Apple = 0
Apple
// Access the Apple member
const schema: Schema.Enums<typeof Fruits>
schema
.
Enums<typeof Fruits>.enums: typeof Fruits
enums
.
function (enum member) Fruits.Banana = 1
Banana
// Access the Banana member

The Schema module includes a built-in Schema.Union constructor for creating “OR” types, allowing you to define schemas that can represent multiple types.

Example (Defining a Union Schema)

import {
import Schema
Schema
} from "effect"
// ┌─── Union<[typeof Schema.String, typeof Schema.Number]>
// ▼
const
const schema: Schema.Union<[typeof Schema.String, typeof Schema.Number]>
schema
=
import Schema
Schema
.
function Union<[typeof Schema.String, typeof Schema.Number]>(members_0: typeof Schema.String, members_1: typeof Schema.Number): Schema.Union<[typeof Schema.String, typeof Schema.Number]> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// ┌─── string | number
// ▼
type
type Type = string | number
Type
= typeof
const schema: Schema.Union<[typeof Schema.String, typeof Schema.Number]>
schema
.
Schema<string | number, string | number, never>.Type: string | number
Type

While you can create a union of literals by combining individual literal schemas:

Example (Using Individual Literal Schemas)

import {
import Schema
Schema
} from "effect"
// ┌─── Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>, Schema.Literal<["c"]>]>
// ▼
const
const schema: Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>, Schema.Literal<["c"]>]>
schema
=
import Schema
Schema
.
function Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>, Schema.Literal<["c"]>]>(members_0: Schema.Literal<["a"]>, members_1: Schema.Literal<["b"]>, members_2: Schema.Literal<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
function Literal<["a"]>(literals_0: "a"): Schema.Literal<["a"]> (+2 overloads)

@since3.10.0

Literal
("a"),
import Schema
Schema
.
function Literal<["b"]>(literals_0: "b"): Schema.Literal<["b"]> (+2 overloads)

@since3.10.0

Literal
("b"),
import Schema
Schema
.
function Literal<["c"]>(literals_0: "c"): Schema.Literal<["c"]> (+2 overloads)

@since3.10.0

Literal
("c")
)

You can simplify the process by passing multiple literals directly to the Schema.Literal constructor:

Example (Defining a Union of Literals)

import {
import Schema
Schema
} from "effect"
// ┌─── Literal<["a", "b", "c"]>
// ▼
const
const schema: Schema.Literal<["a", "b", "c"]>
schema
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c")
// ┌─── "a" | "b" | "c"
// ▼
type
type Type = "a" | "b" | "c"
Type
= typeof
const schema: Schema.Literal<["a", "b", "c"]>
schema
.
Schema<"a" | "b" | "c", "a" | "b" | "c", never>.Type: "a" | "b" | "c"
Type

If you want to set a custom error message for the entire union of literals, you can use the override: true option (see Custom Error Messages for more details) to specify a unified message.

Example (Adding a Custom Message to a Union of Literals)

import {
import Schema
Schema
} from "effect"
// Schema with individual messages for each literal
const
const individualMessages: Schema.Literal<["a", "b", "c"]>
individualMessages
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a" | "b" | "c", "a" | "b" | "c">(schema: Schema.Schema<"a" | "b" | "c", "a" | "b" | "c", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a" | ... 1 more ... | "c"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const individualMessages: Schema.Literal<["a", "b", "c"]>
individualMessages
)(null))
/*
throws:
ParseError: "a" | "b" | "c"
├─ Expected "a", actual null
├─ Expected "b", actual null
└─ Expected "c", actual null
*/
// Schema with a unified custom message for all literals
const
const unifiedMessage: Schema.Literal<["a", "b", "c"]>
unifiedMessage
=
import Schema
Schema
.
function Literal<["a", "b", "c"]>(literals_0: "a", literals_1: "b", literals_2: "c"): Schema.Literal<["a", "b", "c"]> (+2 overloads)

@since3.10.0

Literal
("a", "b", "c").
Annotable<Literal<["a", "b", "c"]>, "a" | "b" | "c", "a" | "b" | "c", never>.annotations(annotations: Schema.Annotations.GenericSchema<"a" | "b" | "c">): Schema.Literal<["a", "b", "c"]>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Schema<"a" | "b" | "c", readonly []>.message?: MessageAnnotation
message
: () => ({
message: string | Effect<string, never, never>
message
: "Not a valid code",
override: boolean
override
: true })
})
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<"a" | "b" | "c", "a" | "b" | "c">(schema: Schema.Schema<"a" | "b" | "c", "a" | "b" | "c", never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => "a" | ... 1 more ... | "c"
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const unifiedMessage: Schema.Literal<["a", "b", "c"]>
unifiedMessage
)(null))
/*
throws:
ParseError: Not a valid code
*/

The Schema module includes utility functions for defining schemas that allow nullable types, helping to handle values that may be null, undefined, or both.

Example (Creating Nullable Schemas)

import {
import Schema
Schema
} from "effect"
// Represents a schema for a string or null value
import Schema
Schema
.
const NullOr: <typeof Schema.String>(self: typeof Schema.String) => Schema.NullOr<typeof Schema.String>

@since3.10.0

NullOr
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
)
// Represents a schema for a string, null, or undefined value
import Schema
Schema
.
const NullishOr: <typeof Schema.String>(self: typeof Schema.String) => Schema.NullishOr<typeof Schema.String>

@since3.10.0

NullishOr
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
)
// Represents a schema for a string or undefined value
import Schema
Schema
.
const UndefinedOr: <typeof Schema.String>(self: typeof Schema.String) => Schema.UndefinedOr<typeof Schema.String>

@since3.10.0

UndefinedOr
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
)

Discriminated unions in TypeScript are a way of modeling complex data structures that may take on different forms based on a specific set of conditions or properties. They allow you to define a type that represents multiple related shapes, where each shape is uniquely identified by a shared discriminant property.

In a discriminated union, each variant of the union has a common property, called the discriminant. The discriminant is a literal type, which means it can only have a finite set of possible values. Based on the value of the discriminant property, TypeScript can infer which variant of the union is currently in use.

Example (Defining a Discriminated Union in TypeScript)

type
type Circle = {
readonly kind: "circle";
readonly radius: number;
}
Circle
= {
readonly
kind: "circle"
kind
: "circle"
readonly
radius: number
radius
: number
}
type
type Square = {
readonly kind: "square";
readonly sideLength: number;
}
Square
= {
readonly
kind: "square"
kind
: "square"
readonly
sideLength: number
sideLength
: number
}
type
type Shape = Circle | Square
Shape
=
type Circle = {
readonly kind: "circle";
readonly radius: number;
}
Circle
|
type Square = {
readonly kind: "square";
readonly sideLength: number;
}
Square

In the Schema module, you can define a discriminated union similarly by specifying a literal field as the discriminant for each type.

Example (Defining a Discriminated Union Using Schema)

import {
import Schema
Schema
} from "effect"
const
const Circle: Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>
Circle
=
import Schema
Schema
.
function Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>(fields: {
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}): Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
kind: Schema.Literal<["circle"]>
kind
:
import Schema
Schema
.
function Literal<["circle"]>(literals_0: "circle"): Schema.Literal<["circle"]> (+2 overloads)

@since3.10.0

Literal
("circle"),
radius: typeof Schema.Number
radius
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Square: Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>
Square
=
import Schema
Schema
.
function Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>(fields: {
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}): Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
kind: Schema.Literal<["square"]>
kind
:
import Schema
Schema
.
function Literal<["square"]>(literals_0: "square"): Schema.Literal<["square"]> (+2 overloads)

@since3.10.0

Literal
("square"),
sideLength: typeof Schema.Number
sideLength
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Shape: Schema.Union<[Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>]>
Shape
=
import Schema
Schema
.
function Union<[Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>]>(members_0: Schema.Struct<...>, members_1: Schema.Struct<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
const Circle: Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>
Circle
,
const Square: Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>
Square
)

In this example, the Schema.Literal constructor sets up the kind property as the discriminant for both Circle and Square schemas. The Shape schema then represents a union of these two types, allowing TypeScript to infer the specific shape based on the kind value.

If you start with a simple union and want to transform it into a discriminated union, you can add a special property to each member. This allows TypeScript to automatically infer the correct type based on the value of the discriminant property.

Example (Initial Simple Union)

For example, let’s say you’ve defined a Shape union as a combination of Circle and Square without any special property:

import {
import Schema
Schema
} from "effect"
const
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
=
import Schema
Schema
.
function Struct<{
radius: typeof Schema.Number;
}>(fields: {
radius: typeof Schema.Number;
}): Schema.Struct<{
radius: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
radius: typeof Schema.Number
radius
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
=
import Schema
Schema
.
function Struct<{
sideLength: typeof Schema.Number;
}>(fields: {
sideLength: typeof Schema.Number;
}): Schema.Struct<{
sideLength: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
sideLength: typeof Schema.Number
sideLength
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Shape: Schema.Union<[Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
sideLength: typeof Schema.Number;
}>]>
Shape
=
import Schema
Schema
.
function Union<[Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
sideLength: typeof Schema.Number;
}>]>(members_0: Schema.Struct<{
radius: typeof Schema.Number;
}>, members_1: Schema.Struct<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
,
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
)

To make your code more manageable, you may want to transform the simple union into a discriminated union. This way, TypeScript will be able to automatically determine which member of the union you’re working with based on the value of a specific property.

To achieve this, you can add a special property to each member of the union, which will allow TypeScript to know which type it’s dealing with at runtime. Here’s how you can transform the Shape schema into another schema that represents a discriminated union:

Example (Adding Discriminant Property)

import {
import Schema
Schema
} from "effect"
const
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
=
import Schema
Schema
.
function Struct<{
radius: typeof Schema.Number;
}>(fields: {
radius: typeof Schema.Number;
}): Schema.Struct<{
radius: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
radius: typeof Schema.Number
radius
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
=
import Schema
Schema
.
function Struct<{
sideLength: typeof Schema.Number;
}>(fields: {
sideLength: typeof Schema.Number;
}): Schema.Struct<{
sideLength: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
sideLength: typeof Schema.Number
sideLength
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const DiscriminatedShape: Schema.Union<[Schema.transform<Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>>, Schema.transform<...>]>
DiscriminatedShape
=
import Schema
Schema
.
function Union<[Schema.transform<Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>>, Schema.transform<...>]>(members_0: Schema.transform<...>, members_1: Schema.transform<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
const transform: <Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>, Schema.Struct<{
radius: typeof Schema.Number;
}>>(from: Schema.Struct<{
radius: typeof Schema.Number;
}>, to: Schema.Struct<...>, options: {
...;
} | {
...;
}) => Schema.transform<...> (+1 overload)

Create a new Schema by transforming the input and output of an existing Schema using the provided mapping functions.

@since3.10.0

transform
(
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
,
// Add a "kind" property with the literal value "circle" to Circle
import Schema
Schema
.
function Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>(fields: {
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}): Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({ ...
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
.
TypeLiteral<{ radius: typeof Number$; }, []>.fields: {
readonly radius: typeof Schema.Number;
}
fields
,
kind: Schema.Literal<["circle"]>
kind
:
import Schema
Schema
.
function Literal<["circle"]>(literals_0: "circle"): Schema.Literal<["circle"]> (+2 overloads)

@since3.10.0

Literal
("circle") }),
{
strict?: true
strict
: true,
// Add the discriminant property to Circle
decode: (fromA: {
readonly radius: number;
}, fromI: {
readonly radius: number;
}) => {
readonly radius: number;
readonly kind: "circle";
}
decode
: (
circle: {
readonly radius: number;
}
circle
) => ({ ...
circle: {
readonly radius: number;
}
circle
,
kind: "circle"
kind
: "circle" as
type const = "circle"
const
}),
// Remove the discriminant property
encode: (toI: {
readonly radius: number;
readonly kind: "circle";
}, toA: {
readonly radius: number;
readonly kind: "circle";
}) => {
readonly radius: number;
}
encode
: ({
kind: "circle"
kind
:
_kind: "circle"
_kind
, ...
rest: {
radius: number;
}
rest
}) =>
rest: {
radius: number;
}
rest
}
),
import Schema
Schema
.
const transform: <Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>, Schema.Struct<{
sideLength: typeof Schema.Number;
}>>(from: Schema.Struct<{
sideLength: typeof Schema.Number;
}>, to: Schema.Struct<...>, options: {
...;
} | {
...;
}) => Schema.transform<...> (+1 overload)

Create a new Schema by transforming the input and output of an existing Schema using the provided mapping functions.

@since3.10.0

transform
(
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
,
// Add a "kind" property with the literal value "square" to Square
import Schema
Schema
.
function Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}>(fields: {
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}): Schema.Struct<{
kind: Schema.Literal<["square"]>;
sideLength: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({ ...
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
.
TypeLiteral<{ sideLength: typeof Number$; }, []>.fields: {
readonly sideLength: typeof Schema.Number;
}
fields
,
kind: Schema.Literal<["square"]>
kind
:
import Schema
Schema
.
function Literal<["square"]>(literals_0: "square"): Schema.Literal<["square"]> (+2 overloads)

@since3.10.0

Literal
("square") }),
{
strict?: true
strict
: true,
// Add the discriminant property to Square
decode: (fromA: {
readonly sideLength: number;
}, fromI: {
readonly sideLength: number;
}) => {
readonly sideLength: number;
readonly kind: "square";
}
decode
: (
square: {
readonly sideLength: number;
}
square
) => ({ ...
square: {
readonly sideLength: number;
}
square
,
kind: "square"
kind
: "square" as
type const = "square"
const
}),
// Remove the discriminant property
encode: (toI: {
readonly sideLength: number;
readonly kind: "square";
}, toA: {
readonly sideLength: number;
readonly kind: "square";
}) => {
readonly sideLength: number;
}
encode
: ({
kind: "square"
kind
:
_kind: "square"
_kind
, ...
rest: {
sideLength: number;
}
rest
}) =>
rest: {
sideLength: number;
}
rest
}
)
)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}>(schema: Schema.Schema<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const DiscriminatedShape: Schema.Union<[Schema.transform<Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>>, Schema.transform<...>]>
DiscriminatedShape
)({
radius: number
radius
: 10 }))
// Output: { radius: 10, kind: 'circle' }
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}>(schema: Schema.Schema<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const DiscriminatedShape: Schema.Union<[Schema.transform<Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.Struct<{
kind: Schema.Literal<["circle"]>;
radius: typeof Schema.Number;
}>>, Schema.transform<...>]>
DiscriminatedShape
)({
sideLength: number
sideLength
: 10 })
)
// Output: { sideLength: 10, kind: 'square' }

The previous solution works perfectly and shows how we can add properties to our schema at will, making it easier to consume the result within our domain model. However, it requires a lot of boilerplate. Fortunately, there is an API called Schema.attachPropertySignature designed specifically for this use case, which allows us to achieve the same result with much less effort:

Example (Using Schema.attachPropertySignature for Less Code)

import {
import Schema
Schema
} from "effect"
const
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
=
import Schema
Schema
.
function Struct<{
radius: typeof Schema.Number;
}>(fields: {
radius: typeof Schema.Number;
}): Schema.Struct<{
radius: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
radius: typeof Schema.Number
radius
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
=
import Schema
Schema
.
function Struct<{
sideLength: typeof Schema.Number;
}>(fields: {
sideLength: typeof Schema.Number;
}): Schema.Struct<{
sideLength: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
sideLength: typeof Schema.Number
sideLength
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const DiscriminatedShape: Schema.Union<[Schema.SchemaClass<{
readonly radius: number;
readonly kind: "circle";
}, {
readonly radius: number;
}, never>, Schema.SchemaClass<{
readonly sideLength: number;
readonly kind: "square";
}, {
...;
}, never>]>
DiscriminatedShape
=
import Schema
Schema
.
function Union<[Schema.SchemaClass<{
readonly radius: number;
readonly kind: "circle";
}, {
readonly radius: number;
}, never>, Schema.SchemaClass<{
readonly sideLength: number;
readonly kind: "square";
}, {
...;
}, never>]>(members_0: Schema.SchemaClass<...>, members_1: Schema.SchemaClass<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
const Circle: Schema.Struct<{
radius: typeof Schema.Number;
}>
Circle
.
Pipeable.pipe<Schema.Struct<{
radius: typeof Schema.Number;
}>, Schema.SchemaClass<{
readonly radius: number;
readonly kind: "circle";
}, {
readonly radius: number;
}, never>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<...>) => Schema.SchemaClass<...>): Schema.SchemaClass<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const attachPropertySignature: <"kind", "circle", {
readonly radius: number;
}>(key: "kind", value: "circle", annotations?: Schema.Annotations.Schema<{
readonly radius: number;
readonly kind: "circle";
}, readonly []> | undefined) => <I, R>(schema: Schema.SchemaClass<...>) => Schema.SchemaClass<...> (+1 overload)

Attaches a property signature with the specified key and value to the schema. This API is useful when you want to add a property to your schema which doesn't describe the shape of the input, but rather maps to another schema, for example when you want to add a discriminant to a simple union.

@paramself - The input schema.

@paramkey - The name of the property to add to the schema.

@paramvalue - The value of the property to add to the schema.

@example

import * as S from "effect/Schema"
import { pipe } from "effect/Function"
const Circle = S.Struct({ radius: S.Number })
const Square = S.Struct({ sideLength: S.Number })
const Shape = S.Union(
Circle.pipe(S.attachPropertySignature("kind", "circle")),
Square.pipe(S.attachPropertySignature("kind", "square"))
)
assert.deepStrictEqual(S.decodeSync(Shape)({ radius: 10 }), {
kind: "circle",
radius: 10
})

@since3.10.0

attachPropertySignature
("kind", "circle")),
const Square: Schema.Struct<{
sideLength: typeof Schema.Number;
}>
Square
.
Pipeable.pipe<Schema.Struct<{
sideLength: typeof Schema.Number;
}>, Schema.SchemaClass<{
readonly sideLength: number;
readonly kind: "square";
}, {
readonly sideLength: number;
}, never>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<...>) => Schema.SchemaClass<...>): Schema.SchemaClass<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const attachPropertySignature: <"kind", "square", {
readonly sideLength: number;
}>(key: "kind", value: "square", annotations?: Schema.Annotations.Schema<{
readonly sideLength: number;
readonly kind: "square";
}, readonly []> | undefined) => <I, R>(schema: Schema.SchemaClass<...>) => Schema.SchemaClass<...> (+1 overload)

Attaches a property signature with the specified key and value to the schema. This API is useful when you want to add a property to your schema which doesn't describe the shape of the input, but rather maps to another schema, for example when you want to add a discriminant to a simple union.

@paramself - The input schema.

@paramkey - The name of the property to add to the schema.

@paramvalue - The value of the property to add to the schema.

@example

import * as S from "effect/Schema"
import { pipe } from "effect/Function"
const Circle = S.Struct({ radius: S.Number })
const Square = S.Struct({ sideLength: S.Number })
const Shape = S.Union(
Circle.pipe(S.attachPropertySignature("kind", "circle")),
Square.pipe(S.attachPropertySignature("kind", "square"))
)
assert.deepStrictEqual(S.decodeSync(Shape)({ radius: 10 }), {
kind: "circle",
radius: 10
})

@since3.10.0

attachPropertySignature
("kind", "square"))
)
// decoding
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}>(schema: Schema.Schema<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const DiscriminatedShape: Schema.Union<[Schema.SchemaClass<{
readonly radius: number;
readonly kind: "circle";
}, {
readonly radius: number;
}, never>, Schema.SchemaClass<{
readonly sideLength: number;
readonly kind: "square";
}, {
...;
}, never>]>
DiscriminatedShape
)({
radius: number
radius
: 10 }))
// Output: { radius: 10, kind: 'circle' }
// encoding
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
encodeSync<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}>(schema: Schema.Schema<{
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, {
readonly radius: number;
} | {
readonly sideLength: number;
}, never>, options?: ParseOptions): (a: {
readonly radius: number;
readonly kind: "circle";
} | {
readonly sideLength: number;
readonly kind: "square";
}, overrideOptions?: ParseOptions) => {
readonly radius: number;
} | {
readonly sideLength: number;
}
export encodeSync

@since3.10.0

encodeSync
(
const DiscriminatedShape: Schema.Union<[Schema.SchemaClass<{
readonly radius: number;
readonly kind: "circle";
}, {
readonly radius: number;
}, never>, Schema.SchemaClass<{
readonly sideLength: number;
readonly kind: "square";
}, {
...;
}, never>]>
DiscriminatedShape
)({
kind: "circle"
kind
: "circle",
radius: number
radius
: 10
})
)
// Output: { radius: 10 }

You can access the individual members of a union schema represented as a tuple:

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.Union<[typeof Schema.String, typeof Schema.Number]>
schema
=
import Schema
Schema
.
function Union<[typeof Schema.String, typeof Schema.Number]>(members_0: typeof Schema.String, members_1: typeof Schema.Number): Schema.Union<[typeof Schema.String, typeof Schema.Number]> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// Accesses the members of the union
const
const members: readonly [typeof Schema.String, typeof Schema.Number]
members
=
const schema: Schema.Union<[typeof Schema.String, typeof Schema.Number]>
schema
.
Union<[typeof String$, typeof Number$]>.members: readonly [typeof Schema.String, typeof Schema.Number]
members
// ┌─── typeof Schema.String
// ▼
const
const firstMember: typeof Schema.String
firstMember
=
const members: readonly [typeof Schema.String, typeof Schema.Number]
members
[0]
// ┌─── typeof Schema.Number
// ▼
const
const secondMember: typeof Schema.Number
secondMember
=
const members: readonly [typeof Schema.String, typeof Schema.Number]
members
[1]

The Schema module allows you to define tuples, which are ordered collections of elements that may have different types. You can define tuples with required, optional, or rest elements.

To define a tuple with required elements, you can use the Schema.Tuple constructor and simply list the element schemas in order:

Example (Defining a Tuple with Required Elements)

import {
import Schema
Schema
} from "effect"
// Define a tuple with a string and a number as required elements
//
// ┌─── Tuple<[typeof Schema.String, typeof Schema.Number]>
// ▼
const
const schema: Schema.Tuple<[typeof Schema.String, typeof Schema.Number]>
schema
=
import Schema
Schema
.
function Tuple<[typeof Schema.String, typeof Schema.Number]>(elements_0: typeof Schema.String, elements_1: typeof Schema.Number): Schema.Tuple<[typeof Schema.String, typeof Schema.Number]> (+1 overload)

@since3.10.0

Tuple
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// ┌─── readonly [string, number]
// ▼
type
type Type = readonly [string, number]
Type
= typeof
const schema: Schema.Tuple<[typeof Schema.String, typeof Schema.Number]>
schema
.
Schema<readonly [string, number], readonly [string, number], never>.Type: readonly [string, number]
Type

You can append additional required elements to an existing tuple by using the spread operator:

Example (Adding an Element to an Existing Tuple)

import {
import Schema
Schema
} from "effect"
const
const tuple1: Schema.Tuple<[typeof Schema.String, typeof Schema.Number]>
tuple1
=
import Schema
Schema
.
function Tuple<[typeof Schema.String, typeof Schema.Number]>(elements_0: typeof Schema.String, elements_1: typeof Schema.Number): Schema.Tuple<[typeof Schema.String, typeof Schema.Number]> (+1 overload)

@since3.10.0

Tuple
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// Append a boolean to the existing tuple
const
const tuple2: Schema.Tuple<[typeof Schema.String, typeof Schema.Number, typeof Schema.Boolean]>
tuple2
=
import Schema
Schema
.
function Tuple<[typeof Schema.String, typeof Schema.Number, typeof Schema.Boolean]>(elements_0: typeof Schema.String, elements_1: typeof Schema.Number, elements_2: typeof Schema.Boolean): Schema.Tuple<...> (+1 overload)

@since3.10.0

Tuple
(...
const tuple1: Schema.Tuple<[typeof Schema.String, typeof Schema.Number]>
tuple1
.
TupleType<[typeof String$, typeof Number$], []>.elements: readonly [typeof Schema.String, typeof Schema.Number]
elements
,
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
)
// ┌─── readonly [string, number, boolean]
// ▼
type
type Type = readonly [string, number, boolean]
Type
= typeof
const tuple2: Schema.Tuple<[typeof Schema.String, typeof Schema.Number, typeof Schema.Boolean]>
tuple2
.
Schema<readonly [string, number, boolean], readonly [string, number, boolean], never>.Type: readonly [string, number, boolean]
Type

To define an optional element, use the Schema.optionalElement constructor.

Example (Defining a Tuple with Optional Elements)

import {
import Schema
Schema
} from "effect"
// Define a tuple with a required string and an optional number
const
const schema: Schema.Tuple<[typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]>
schema
=
import Schema
Schema
.
function Tuple<[typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]>(elements_0: typeof Schema.String, elements_1: Schema.Element<typeof Schema.Number, "?">): Schema.Tuple<...> (+1 overload)

@since3.10.0

Tuple
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
, // required element
import Schema
Schema
.
const optionalElement: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "?">

@since3.10.0

optionalElement
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
) // optional element
)
// ┌─── readonly [string, number?]
// ▼
type
type Type = readonly [string, number?]
Type
= typeof
const schema: Schema.Tuple<[typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]>
schema
.
Schema<readonly [string, number?], readonly [string, number?], never>.Type: readonly [string, number?]
Type

To define a rest element, add it after the list of required or optional elements. The rest element allows the tuple to accept additional elements of a specific type.

Example (Using a Rest Element)

import {
import Schema
Schema
} from "effect"
// Define a tuple with required elements and a rest element of type boolean
const
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean]>
schema
=
import Schema
Schema
.
function Tuple<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean]>(elements: readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], rest_0: typeof Schema.Boolean): Schema.TupleType<...> (+1 overload)

@since3.10.0

Tuple
(
[
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
const optionalElement: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "?">

@since3.10.0

optionalElement
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)], // elements
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
// rest element
)
// ┌─── readonly [string, number?, ...boolean[]]
// ▼
type
type Type = readonly [string, number?, ...boolean[]]
Type
= typeof
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean]>
schema
.
Schema<readonly [string, number?, ...boolean[]], readonly [string, number?, ...boolean[]], never>.Type: readonly [string, number?, ...boolean[]]
Type

You can also include other elements after the rest:

Example (Including Additional Elements After a Rest Element)

import {
import Schema
Schema
} from "effect"
// Define a tuple with required elements, a rest element,
// and an additional element
const
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>
schema
=
import Schema
Schema
.
function Tuple<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>(elements: readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], rest_0: typeof Schema.Boolean, rest_1: typeof Schema.String): Schema.TupleType<...> (+1 overload)

@since3.10.0

Tuple
(
[
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
const optionalElement: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "?">

@since3.10.0

optionalElement
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)], // elements
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
, // rest element
import Schema
Schema
.
class String
export String

@since3.10.0

String
// additional element
)
// ┌─── readonly [string, number | undefined, ...boolean[], string]
// ▼
type
type Type = readonly [string, number | undefined, ...boolean[], string]
Type
= typeof
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>
schema
.
Schema<readonly [string, number | undefined, ...boolean[], string], readonly [string, number | undefined, ...boolean[], string], never>.Type: readonly [string, number | undefined, ...boolean[], string]
Type

Annotations are useful for adding metadata to tuple elements, making it easier to describe their purpose or requirements. This is especially helpful for generating documentation or JSON schemas.

Example (Adding Annotations to Tuple Elements)

import {
import JSONSchema
JSONSchema
,
import Schema
Schema
} from "effect"
// Define a tuple representing a point with annotations for each coordinate
const
const Point: Schema.Tuple<[Schema.Element<typeof Schema.Number, "">, Schema.Element<typeof Schema.Number, "?">]>
Point
=
import Schema
Schema
.
function Tuple<[Schema.Element<typeof Schema.Number, "">, Schema.Element<typeof Schema.Number, "?">]>(elements_0: Schema.Element<typeof Schema.Number, "">, elements_1: Schema.Element<...>): Schema.Tuple<...> (+1 overload)

@since3.10.0

Tuple
(
import Schema
Schema
.
const element: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "">

@since3.10.0

element
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
).
Element<typeof Number$, "">.annotations(annotations: Schema.Element<S extends Schema.Schema<in out A, in out I = A, out R = never>.Any, Token extends Schema.Element.Token>.Annotations<number>): Schema.Element<typeof Schema.Number, "">
annotations
({
Annotations.Doc<number>.title?: string
title
: "X",
Annotations.Doc<number>.description?: string
description
: "X coordinate"
}),
import Schema
Schema
.
const optionalElement: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "?">

@since3.10.0

optionalElement
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
).
Element<typeof Number$, "?">.annotations(annotations: Schema.Element<S extends Schema.Schema<in out A, in out I = A, out R = never>.Any, Token extends Schema.Element.Token>.Annotations<number>): Schema.Element<typeof Schema.Number, "?">
annotations
({
Annotations.Doc<number>.title?: string
title
: "Y",
Annotations.Doc<number>.description?: string
description
: "optional Y coordinate"
})
)
// Generate a JSON Schema from the tuple
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import JSONSchema
JSONSchema
.
const make: <readonly [number, number?], readonly [number, number?], never>(schema: Schema.Schema<readonly [number, number?], readonly [number, number?], never>) => JSONSchema.JsonSchema7Root

@since3.10.0

make
(
const Point: Schema.Tuple<[Schema.Element<typeof Schema.Number, "">, Schema.Element<typeof Schema.Number, "?">]>
Point
))
/*
Output:
{
'$schema': 'http://json-schema.org/draft-07/schema#',
type: 'array',
minItems: 1,
items: [
{ type: 'number', description: 'X coordinate', title: 'X' },
{
type: 'number',
description: 'optional Y coordinate',
title: 'Y'
}
],
additionalItems: false
}
*/

You can access the elements and rest elements of a tuple schema using the elements and rest properties:

Example (Accessing Elements and Rest Element in a Tuple Schema)

import {
import Schema
Schema
} from "effect"
// Define a tuple with required, optional, and rest elements
const
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>
schema
=
import Schema
Schema
.
function Tuple<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>(elements: readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], rest_0: typeof Schema.Boolean, rest_1: typeof Schema.String): Schema.TupleType<...> (+1 overload)

@since3.10.0

Tuple
(
[
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
import Schema
Schema
.
const optionalElement: <typeof Schema.Number>(self: typeof Schema.Number) => Schema.Element<typeof Schema.Number, "?">

@since3.10.0

optionalElement
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)], // elements
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
, // rest element
import Schema
Schema
.
class String
export String

@since3.10.0

String
// additional element
)
// Access the required and optional elements of the tuple
//
// ┌─── readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]
// ▼
const
const tupleElements: readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]
tupleElements
=
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>
schema
.
TupleType<readonly [typeof String$, Element<typeof Number$, "?">], [typeof Boolean$, typeof String$]>.elements: readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">]
elements
// Access the rest element of the tuple
//
// ┌─── readonly [typeof Schema.Boolean, typeof Schema.String]
// ▼
const
const restElement: readonly [typeof Schema.Boolean, typeof Schema.String]
restElement
=
const schema: Schema.TupleType<readonly [typeof Schema.String, Schema.Element<typeof Schema.Number, "?">], [typeof Schema.Boolean, typeof Schema.String]>
schema
.
TupleType<readonly [typeof String$, Element<typeof Number$, "?">], [typeof Boolean$, typeof String$]>.rest: readonly [typeof Schema.Boolean, typeof Schema.String]
rest

The Schema module allows you to define schemas for arrays, making it easy to validate collections of elements of a specific type.

Example (Defining an Array Schema)

import {
import Schema
Schema
} from "effect"
// Define a schema for an array of numbers
//
// ┌─── Array$<typeof Schema.Number>
// ▼
const
const schema: Schema.Array$<typeof Schema.Number>
schema
=
import Schema
Schema
.
Array<typeof Schema.Number>(value: typeof Schema.Number): Schema.Array$<typeof Schema.Number>
export Array

@since3.10.0

Array
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// ┌─── readonly number[]
// ▼
type
type Type = readonly number[]
Type
= typeof
const schema: Schema.Array$<typeof Schema.Number>
schema
.
Schema<readonly number[], readonly number[], never>.Type: readonly number[]
Type

By default, Schema.Array generates a type marked as readonly. To create a schema for a mutable array, you can use the Schema.mutable function, which makes the array type mutable in a shallow manner.

Example (Creating a Mutable Array Schema)

import {
import Schema
Schema
} from "effect"
// Define a schema for a mutable array of numbers
//
// ┌─── mutable<Schema.Array$<typeof Schema.Number>>
// ▼
const
const schema: Schema.mutable<Schema.Array$<typeof Schema.Number>>
schema
=
import Schema
Schema
.
const mutable: <Schema.Array$<typeof Schema.Number>>(schema: Schema.Array$<typeof Schema.Number>) => Schema.mutable<Schema.Array$<typeof Schema.Number>>

Creates a new schema with shallow mutability applied to its properties.

@paramschema - The original schema to make properties mutable (shallowly).

@since3.10.0

mutable
(
import Schema
Schema
.
Array<typeof Schema.Number>(value: typeof Schema.Number): Schema.Array$<typeof Schema.Number>
export Array

@since3.10.0

Array
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
))
// ┌─── number[]
// ▼
type
type Type = number[]
Type
= typeof
const schema: Schema.mutable<Schema.Array$<typeof Schema.Number>>
schema
.
Schema<number[], number[], never>.Type: number[]
Type

You can access the value type of an array schema using the value property:

Example (Accessing the Value Type of an Array Schema)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.Array$<typeof Schema.Number>
schema
=
import Schema
Schema
.
Array<typeof Schema.Number>(value: typeof Schema.Number): Schema.Array$<typeof Schema.Number>
export Array

@since3.10.0

Array
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// Access the value type of the array schema
//
// ┌─── typeof Schema.Number
// ▼
const
const value: typeof Schema.Number
value
=
const schema: Schema.Array$<typeof Schema.Number>
schema
.
Array$<typeof Number$>.value: typeof Schema.Number
value

The Schema module also provides a way to define schemas for non-empty arrays, ensuring that the array always contains at least one element.

Example (Defining a Non-Empty Array Schema)

import {
import Schema
Schema
} from "effect"
// Define a schema for a non-empty array of numbers
//
// ┌─── NonEmptyArray<typeof Schema.Number>
// ▼
const
const schema: Schema.NonEmptyArray<typeof Schema.Number>
schema
=
import Schema
Schema
.
const NonEmptyArray: <typeof Schema.Number>(value: typeof Schema.Number) => Schema.NonEmptyArray<typeof Schema.Number>

@since3.10.0

NonEmptyArray
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// ┌─── readonly [number, ...number[]]
// ▼
type
type Type = readonly [number, ...number[]]
Type
= typeof
const schema: Schema.NonEmptyArray<typeof Schema.Number>
schema
.
Schema<readonly [number, ...number[]], readonly [number, ...number[]], never>.Type: readonly [number, ...number[]]
Type

You can access the value type of a non-empty array schema using the value property:

Example (Accessing the Value Type of a Non-Empty Array Schema)

import {
import Schema
Schema
} from "effect"
// Define a schema for a non-empty array of numbers
const
const schema: Schema.NonEmptyArray<typeof Schema.Number>
schema
=
import Schema
Schema
.
const NonEmptyArray: <typeof Schema.Number>(value: typeof Schema.Number) => Schema.NonEmptyArray<typeof Schema.Number>

@since3.10.0

NonEmptyArray
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
)
// Access the value type of the non-empty array schema
//
// ┌─── typeof Schema.Number
// ▼
const
const value: typeof Schema.Number
value
=
const schema: Schema.NonEmptyArray<typeof Schema.Number>
schema
.
NonEmptyArray<typeof Number$>.value: typeof Schema.Number
value

The Schema module provides support for defining record types, which are collections of key-value pairs where the key can be a string, symbol, or other types, and the value has a defined schema.

You can define a record with string keys and a specified type for the values.

Example (String Keys with Number Values)

import {
import Schema
Schema
} from "effect"
// Define a record schema with string keys and number values
//
// ┌─── Record$<typeof Schema.String, typeof Schema.Number>
// ▼
const
const schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <typeof Schema.String, typeof Schema.Number>(options: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.String, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly [x: string]: number; }
// ▼
type
type Type = {
readonly [x: string]: number;
}
Type
= typeof
const schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>
schema
.
Schema<{ readonly [x: string]: number; }, { readonly [x: string]: number; }, never>.Type: {
readonly [x: string]: number;
}
Type

Records can also use symbols as keys.

Example (Symbol Keys with Number Values)

import {
import Schema
Schema
} from "effect"
// Define a record schema with symbol keys and number values
const
const schema: Schema.Record$<typeof Schema.SymbolFromSelf, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <typeof Schema.SymbolFromSelf, typeof Schema.Number>(options: {
readonly key: typeof Schema.SymbolFromSelf;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.SymbolFromSelf, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.SymbolFromSelf
key
:
import Schema
Schema
.
class SymbolFromSelf

@since3.10.0

SymbolFromSelf
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly [x: symbol]: number; }
// ▼
type
type Type = {
readonly [x: symbol]: number;
}
Type
= typeof
const schema: Schema.Record$<typeof Schema.SymbolFromSelf, typeof Schema.Number>
schema
.
Schema<{ readonly [x: symbol]: number; }, { readonly [x: symbol]: number; }, never>.Type: {
readonly [x: symbol]: number;
}
Type

Use a union of literals to restrict keys to a specific set of values.

Example (Union of String Literals as Keys)

import {
import Schema
Schema
} from "effect"
// Define a record schema where keys are limited
// to specific string literals ("a" or "b")
const
const schema: Schema.Record$<Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>, typeof Schema.Number>(options: {
readonly key: Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>;
readonly value: typeof Schema.Number;
}) => Schema.Record$<...>

@since3.10.0

Record
({
key: Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>
key
:
import Schema
Schema
.
function Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>(members_0: Schema.Literal<["a"]>, members_1: Schema.Literal<["b"]>): Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<...>]> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
function Literal<["a"]>(literals_0: "a"): Schema.Literal<["a"]> (+2 overloads)

@since3.10.0

Literal
("a"),
import Schema
Schema
.
function Literal<["b"]>(literals_0: "b"): Schema.Literal<["b"]> (+2 overloads)

@since3.10.0

Literal
("b")),
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly a: number; readonly b: number; }
// ▼
type
type Type = {
readonly a: number;
readonly b: number;
}
Type
= typeof
const schema: Schema.Record$<Schema.Union<[Schema.Literal<["a"]>, Schema.Literal<["b"]>]>, typeof Schema.Number>
schema
.
Schema<{ readonly a: number; readonly b: number; }, { readonly a: number; readonly b: number; }, never>.Type: {
readonly a: number;
readonly b: number;
}
Type

Records can use template literals as keys, allowing for more complex key patterns.

Example (Template Literal Keys with Number Values)

import {
import Schema
Schema
} from "effect"
// Define a record schema with keys that match
// the template literal pattern "a${string}"
const
const schema: Schema.Record$<Schema.TemplateLiteral<`a${string}`>, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <Schema.TemplateLiteral<`a${string}`>, typeof Schema.Number>(options: {
readonly key: Schema.TemplateLiteral<`a${string}`>;
readonly value: typeof Schema.Number;
}) => Schema.Record$<...>

@since3.10.0

Record
({
key: Schema.TemplateLiteral<`a${string}`>
key
:
import Schema
Schema
.
const TemplateLiteral: <[Schema.Literal<["a"]>, typeof Schema.String]>(head: Schema.Literal<["a"]>, tail_0: typeof Schema.String) => Schema.TemplateLiteral<`a${string}`>

@since3.10.0

TemplateLiteral
(
import Schema
Schema
.
function Literal<["a"]>(literals_0: "a"): Schema.Literal<["a"]> (+2 overloads)

@since3.10.0

Literal
("a"),
import Schema
Schema
.
class String
export String

@since3.10.0

String
),
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly [x: `a${string}`]: number; }
// ▼
type
type Type = {
readonly [x: `a${string}`]: number;
}
Type
= typeof
const schema: Schema.Record$<Schema.TemplateLiteral<`a${string}`>, typeof Schema.Number>
schema
.
Schema<{ readonly [x: `a${string}`]: number; }, { readonly [x: `a${string}`]: number; }, never>.Type: {
readonly [x: `a${string}`]: number;
}
Type

You can refine the key type with additional constraints.

Example (Refined Keys with Minimum Length Constraint)

import {
import Schema
Schema
} from "effect"
// Define a record schema where keys are strings with a minimum length of 2
const
const schema: Schema.Record$<Schema.filter<Schema.Schema<string, string, never>>, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <Schema.filter<Schema.Schema<string, string, never>>, typeof Schema.Number>(options: {
readonly key: Schema.filter<Schema.Schema<string, string, never>>;
readonly value: typeof Schema.Number;
}) => Schema.Record$<...>

@since3.10.0

Record
({
key: Schema.filter<Schema.Schema<string, string, never>>
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
.
Pipeable.pipe<typeof Schema.String, Schema.filter<Schema.Schema<string, string, never>>>(this: typeof Schema.String, ab: (_: typeof Schema.String) => Schema.filter<Schema.Schema<string, string, never>>): Schema.filter<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const minLength: <string>(minLength: number, annotations?: Schema.Annotations.Filter<string, string> | undefined) => <I, R>(self: Schema.Schema<string, I, R>) => Schema.filter<...>

@since3.10.0

minLength
(2)),
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly [x: string]: number; }
// ▼
type
type Type = {
readonly [x: string]: number;
}
Type
= typeof
const schema: Schema.Record$<Schema.filter<Schema.Schema<string, string, never>>, typeof Schema.Number>
schema
.
Schema<{ readonly [x: string]: number; }, { readonly [x: string]: number; }, never>.Type: {
readonly [x: string]: number;
}
Type

By default, Schema.Record generates a type marked as readonly. To create a schema for a mutable record, you can use the Schema.mutable function, which makes the record type mutable in a shallow manner.

Example (Creating a Mutable Record Schema)

import {
import Schema
Schema
} from "effect"
// Create a schema for a mutable record with string keys and number values
const
const schema: Schema.mutable<Schema.Record$<typeof Schema.String, typeof Schema.Number>>
schema
=
import Schema
Schema
.
const mutable: <Schema.Record$<typeof Schema.String, typeof Schema.Number>>(schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>) => Schema.mutable<Schema.Record$<typeof Schema.String, typeof Schema.Number>>

Creates a new schema with shallow mutability applied to its properties.

@paramschema - The original schema to make properties mutable (shallowly).

@since3.10.0

mutable
(
import Schema
Schema
.
const Record: <typeof Schema.String, typeof Schema.Number>(options: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.String, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// ┌─── { [x: string]: number; }
// ▼
type
type Type = {
[x: string]: number;
}
Type
= typeof
const schema: Schema.mutable<Schema.Record$<typeof Schema.String, typeof Schema.Number>>
schema
.
Schema<{ [x: string]: number; }, { [x: string]: number; }, never>.Type: {
[x: string]: number;
}
Type

You can access the key and value types of a record schema using the key and value properties:

Example (Accessing Key and Value Types)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>
schema
=
import Schema
Schema
.
const Record: <typeof Schema.String, typeof Schema.Number>(options: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.String, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// Accesses the key
//
// ┌─── typeof Schema.String
// ▼
const
const key: typeof Schema.String
key
=
const schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>
schema
.
Record$<typeof String$, typeof Number$>.key: typeof Schema.String
key
// Accesses the value
//
// ┌─── typeof Schema.Number
// ▼
const
const value: typeof Schema.Number
value
=
const schema: Schema.Record$<typeof Schema.String, typeof Schema.Number>
schema
.
Record$<typeof String$, typeof Number$>.value: typeof Schema.Number
value

The Schema.Struct constructor allows you to define a schema for an object with specific properties.

Example (Defining a Struct Schema)

import {
import Schema
Schema
} from "effect"
// Define a struct schema for an object with properties:
// - "name" (string)
// - "age" (number)
//
// ┌─── Schema.Struct<{
// │ name: typeof Schema.String;
// │ age: typeof Schema.Number;
// │ }>
// ▼
const
const schema: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
schema
=
import Schema
Schema
.
function Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly name: string; readonly age: number; }
// ▼
type
type Type = {
readonly name: string;
readonly age: number;
}
Type
= typeof
const schema: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
schema
.
Schema<{ readonly name: string; readonly age: number; }, { readonly name: string; readonly age: number; }, never>.Type: {
readonly name: string;
readonly age: number;
}
Type

The Schema.Struct constructor can optionally accept a list of key/value pairs representing index signatures, allowing you to define additional dynamic properties.

declare const Struct: (props, ...indexSignatures) => Struct<...>

Example (Adding an Index Signature)

import {
import Schema
Schema
} from "effect"
// Define a struct with a specific property "a"
// and an index signature for other properties
const
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [{
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}]>
schema
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.Number;
}, readonly [{
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}]>(fields: {
a: typeof Schema.Number;
}, records_0: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}): Schema.TypeLiteral<...> (+1 overload)

@since3.10.0

Struct
(
{
a: typeof Schema.Number
a
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
},
{
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
}
)
// ┌─── { readonly [x: string]: number; readonly a: number; }
// ▼
type
type Type = {
readonly [x: string]: number;
readonly a: number;
}
Type
= typeof
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [{
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}]>
schema
.
Schema<{ readonly [x: string]: number; readonly a: number; }, { readonly [x: string]: number; readonly a: number; }, never>.Type: {
readonly [x: string]: number;
readonly a: number;
}
Type

Since the Schema.Record constructor returns a schema that exposes both the key and value, you can simplify the above code by using the Schema.Record constructor:

Example (Simplifying with Schema.Record)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>
schema
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>(fields: {
a: typeof Schema.Number;
}, records_0: Schema.Record$<typeof Schema.String, typeof Schema.Number>): Schema.TypeLiteral<...> (+1 overload)

@since3.10.0

Struct
(
{
a: typeof Schema.Number
a
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
},
import Schema
Schema
.
const Record: <typeof Schema.String, typeof Schema.Number>(options: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.String, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// ┌─── { readonly [x: string]: number; readonly a: number; }
// ▼
type
type Type = {
readonly [x: string]: number;
readonly a: number;
}
Type
= typeof
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>
schema
.
Schema<{ readonly [x: string]: number; readonly a: number; }, { readonly [x: string]: number; readonly a: number; }, never>.Type: {
readonly [x: string]: number;
readonly a: number;
}
Type

By default, Schema.Struct generates a type with properties marked as readonly. To create a mutable version of the struct, use the Schema.mutable function, which makes the properties mutable in a shallow manner.

Example (Creating a Mutable Struct Schema)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.mutable<Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>>
schema
=
import Schema
Schema
.
const mutable: <Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>>(schema: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>) => Schema.mutable<Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>>

Creates a new schema with shallow mutability applied to its properties.

@paramschema - The original schema to make properties mutable (shallowly).

@since3.10.0

mutable
(
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.Number;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// ┌─── { a: string; b: number; }
// ▼
type
type Type = {
a: string;
b: number;
}
Type
= typeof
const schema: Schema.mutable<Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>>
schema
.
Schema<{ a: string; b: number; }, { a: string; b: number; }, never>.Type: {
a: string;
b: number;
}
Type

You can access the fields and records of a struct schema using the fields and records properties:

Example (Accessing Fields and Records)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>
schema
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>(fields: {
a: typeof Schema.Number;
}, records_0: Schema.Record$<typeof Schema.String, typeof Schema.Number>): Schema.TypeLiteral<...> (+1 overload)

@since3.10.0

Struct
(
{
a: typeof Schema.Number
a
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
},
import Schema
Schema
.
const Record: <typeof Schema.String, typeof Schema.Number>(options: {
readonly key: typeof Schema.String;
readonly value: typeof Schema.Number;
}) => Schema.Record$<typeof Schema.String, typeof Schema.Number>

@since3.10.0

Record
({
key: typeof Schema.String
key
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
value: typeof Schema.Number
value
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// Accesses the fields
//
// ┌─── { readonly a: typeof Schema.Number; }
// ▼
const
const fields: {
readonly a: typeof Schema.Number;
}
fields
=
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>
schema
.
TypeLiteral<{ a: typeof Number$; }, readonly [Record$<typeof String$, typeof Number$>]>.fields: {
readonly a: typeof Schema.Number;
}
fields
// Accesses the records
//
// ┌─── readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]
// ▼
const
const records: readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]
records
=
const schema: Schema.TypeLiteral<{
a: typeof Schema.Number;
}, readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]>
schema
.
TypeLiteral<{ a: typeof Number$; }, readonly [Record$<typeof String$, typeof Number$>]>.records: readonly [Schema.Record$<typeof Schema.String, typeof Schema.Number>]
records

In TypeScript tags help to enhance type discrimination and pattern matching by providing a simple yet powerful way to define and recognize different data types.

A tag is a literal value added to data structures, commonly used in structs, to distinguish between various object types or variants within tagged unions. This literal acts as a discriminator, making it easier to handle and process different types of data correctly and efficiently.

The Schema.tag constructor is specifically designed to create a property signature that holds a specific literal value, serving as the discriminator for object types.

Example (Defining a Tagged Struct)

import {
import Schema
Schema
} from "effect"
const
const User: Schema.Struct<{
_tag: Schema.tag<"User">;
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
=
import Schema
Schema
.
function Struct<{
_tag: Schema.tag<"User">;
name: typeof Schema.String;
age: typeof Schema.Number;
}>(fields: {
_tag: Schema.tag<"User">;
name: typeof Schema.String;
age: typeof Schema.Number;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
_tag: Schema.tag<"User">
_tag
:
import Schema
Schema
.
const tag: <"User">(tag: "User") => Schema.tag<"User">

Returns a property signature that represents a tag. A tag is a literal value that is used to distinguish between different types of objects. The tag is optional when using the make method.

@seeTaggedStruct

@example

import { Schema } from "effect"
const User = Schema.Struct({
_tag: Schema.tag("User"),
name: Schema.String,
age: Schema.Number
})
assert.deepStrictEqual(User.make({ name: "John", age: 44 }), { _tag: "User", name: "John", age: 44 })

@since3.10.0

tag
("User"),
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// ┌─── { readonly _tag: "User"; readonly name: string; readonly age: number; }
// ▼
type
type Type = {
readonly _tag: "User";
readonly name: string;
readonly age: number;
}
Type
= typeof
const User: Schema.Struct<{
_tag: Schema.tag<"User">;
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
.
Schema<{ readonly _tag: "User"; readonly name: string; readonly age: number; }, { readonly _tag: "User"; readonly name: string; readonly age: number; }, never>.Type: {
readonly _tag: "User";
readonly name: string;
readonly age: number;
}
Type
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const User: Schema.Struct<{
_tag: Schema.tag<"User">;
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
.
TypeLiteral<{ _tag: tag<"User">; name: typeof String$; age: typeof Number$; }, []>.make(props: {
readonly _tag?: "User";
readonly name: string;
readonly age: number;
}, options?: MakeOptions): {
readonly _tag: "User";
readonly name: string;
readonly age: number;
}
make
({
name: string
name
: "John",
age: number
age
: 44 }))
/*
Output:
{ _tag: 'User', name: 'John', age: 44 }
*/

In the example above, Schema.tag("User") attaches a _tag property to the User struct schema, effectively labeling objects of this struct type as “User”. This label is automatically applied when using the make method to create new instances, simplifying object creation and ensuring consistent tagging.

The Schema.TaggedStruct constructor streamlines the process of creating tagged structs by directly integrating the tag into the struct definition. This method provides a clearer and more declarative approach to building data structures with embedded discriminators.

Example (Using TaggedStruct for a Simplified Tagged Struct)

import {
import Schema
Schema
} from "effect"
const
const User: Schema.TaggedStruct<"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
=
import Schema
Schema
.
const TaggedStruct: <"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>(value: "User", fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}) => Schema.TaggedStruct<"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>

A tagged struct is a struct that has a tag property that is used to distinguish between different types of objects.

The tag is optional when using the make method.

@example

import { Schema } from "effect"
const User = Schema.TaggedStruct("User", {
name: Schema.String,
age: Schema.Number
})
assert.deepStrictEqual(User.make({ name: "John", age: 44 }), { _tag: "User", name: "John", age: 44 })

@since3.10.0

TaggedStruct
("User", {
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// `_tag` is automatically applied when constructing an instance
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const User: Schema.TaggedStruct<"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
.
TypeLiteral<{ _tag: tag<"User">; } & { name: typeof String$; age: typeof Number$; }, []>.make(props: {
readonly name: string;
readonly age: number;
readonly _tag?: "User";
}, options?: MakeOptions): {
readonly name: string;
readonly age: number;
readonly _tag: "User";
}
make
({
name: string
name
: "John",
age: number
age
: 44 }))
// Output: { _tag: 'User', name: 'John', age: 44 }
// `_tag` is required when decoding from an unknown source
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<{
readonly name: string;
readonly age: number;
readonly _tag: "User";
}, {
readonly name: string;
readonly age: number;
readonly _tag: "User";
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
readonly _tag: "User";
}, {
readonly name: string;
readonly age: number;
readonly _tag: "User";
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly name: string;
readonly age: number;
readonly _tag: "User";
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const User: Schema.TaggedStruct<"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
)({
name: string
name
: "John",
age: number
age
: 44 }))
/*
throws:
ParseError: { readonly _tag: "User"; readonly name: string; readonly age: number }
└─ ["_tag"]
└─ is missing
*/

In this example:

  • The _tag property is optional when constructing an instance with make, allowing the schema to automatically apply it.
  • When decoding unknown data, _tag is required to ensure correct type identification. This distinction between instance construction and decoding is useful for preserving the tag’s role as a type discriminator while simplifying instance creation.

If you need _tag to be applied automatically during decoding as well, you can create a customized version of Schema.TaggedStruct:

Example (Custom TaggedStruct with _tag Applied during Decoding)

import type {
import SchemaAST
SchemaAST
} from "effect"
import {
import Schema
Schema
} from "effect"
const
const TaggedStruct: <Tag extends SchemaAST.LiteralValue, Fields extends Schema.Struct.Fields>(tag: Tag, fields: Fields) => Schema.Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>
TaggedStruct
= <
function (type parameter) Tag in <Tag extends SchemaAST.LiteralValue, Fields extends Schema.Struct.Fields>(tag: Tag, fields: Fields): Schema.Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>
Tag
extends
import SchemaAST
SchemaAST
.
type LiteralValue = string | number | bigint | boolean | null

@since3.10.0

LiteralValue
,
function (type parameter) Fields in <Tag extends SchemaAST.LiteralValue, Fields extends Schema.Struct.Fields>(tag: Tag, fields: Fields): Schema.Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>
Fields
extends
import Schema
Schema
.
namespace Struct

@since3.10.0

@since3.10.0

@since3.10.0

Struct
.
type Struct<Fields extends Struct.Fields>.Fields = {
readonly [x: string]: Schema.Schema.All | Schema.PropertySignature.All<PropertyKey>;
readonly [x: number]: Schema.Schema.All | Schema.PropertySignature.All<PropertyKey>;
readonly [x: symbol]: Schema.Schema.All | Schema.PropertySignature.All<...>;
}

@since3.10.0

Fields
>(
tag: Tag extends SchemaAST.LiteralValue
tag
:
function (type parameter) Tag in <Tag extends SchemaAST.LiteralValue, Fields extends Schema.Struct.Fields>(tag: Tag, fields: Fields): Schema.Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>
Tag
,
fields: Fields extends Schema.Struct.Fields
fields
:
function (type parameter) Fields in <Tag extends SchemaAST.LiteralValue, Fields extends Schema.Struct.Fields>(tag: Tag, fields: Fields): Schema.Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>
Fields
) =>
import Schema
Schema
.
function Struct<{
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields>(fields: {
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>;
} & Fields): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
_tag: Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>
_tag
:
import Schema
Schema
.
function Literal<[Tag]>(literals_0: Tag): Schema.Literal<[Tag]> (+2 overloads)

@since3.10.0

Literal
(
tag: Tag extends SchemaAST.LiteralValue
tag
).
Pipeable.pipe<Schema.Literal<[Tag]>, Schema.optional<Schema.Literal<[Tag]>>, Schema.PropertySignature<":", Exclude<Tag, undefined>, never, "?:", Tag | undefined, true, never>>(this: Schema.Literal<...>, ab: (_: Schema.Literal<...>) => Schema.optional<...>, bc: (_: Schema.optional<...>) => Schema.PropertySignature<...>): Schema.PropertySignature<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const optional: <S extends Schema.Schema.All>(self: S) => Schema.optional<S>

@since3.10.0

@since3.10.0

optional
,
import Schema
Schema
.
const withDefaults: <Tag | undefined>(defaults: {
constructor: () => NoInfer<Exclude<Tag, undefined>>;
decoding: () => NoInfer<Tag | undefined>;
}) => <Key, Encoded, R>(self: Schema.PropertySignature<...>) => Schema.PropertySignature<...> (+1 overload)

Enhances a property signature with a default decoding value and a default constructor value.

@since3.10.0

withDefaults
({
constructor: () => NoInfer<Exclude<Tag, undefined>>
constructor
: () =>
tag: Tag extends SchemaAST.LiteralValue
tag
, // Apply _tag during instance construction
decoding: () => NoInfer<Tag | undefined>
decoding
: () =>
tag: Tag extends SchemaAST.LiteralValue
tag
// Apply _tag during decoding
})
),
...
fields: Fields extends Schema.Struct.Fields
fields
})
const
const User: Schema.Struct<{
_tag: Schema.PropertySignature<":", "User", never, "?:", "User" | undefined, true, never>;
} & {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
=
const TaggedStruct: <"User", {
name: typeof Schema.String;
age: typeof Schema.Number;
}>(tag: "User", fields: {
name: typeof Schema.String;
age: typeof Schema.Number;
}) => Schema.Struct<{
_tag: Schema.PropertySignature<":", "User", never, "?:", "User" | undefined, true, never>;
} & {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
TaggedStruct
("User", {
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
age: typeof Schema.Number
age
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const User: Schema.Struct<{
_tag: Schema.PropertySignature<":", "User", never, "?:", "User" | undefined, true, never>;
} & {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
.
TypeLiteral<{ _tag: PropertySignature<":", "User", never, "?:", "User" | undefined, true, never>; } & { name: typeof String$; age: typeof Number$; }, []>.make(props: {
readonly _tag?: "User";
readonly name: string;
readonly age: number;
}, options?: MakeOptions): {
readonly _tag: "User";
readonly name: string;
readonly age: number;
}
make
({
name: string
name
: "John",
age: number
age
: 44 }))
// Output: { _tag: 'User', name: 'John', age: 44 }
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<{
readonly _tag: "User";
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
readonly _tag?: "User" | undefined;
}>(schema: Schema.Schema<{
readonly _tag: "User";
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
readonly _tag?: "User" | undefined;
}, never>, options?: SchemaAST.ParseOptions): (u: unknown, overrideOptions?: SchemaAST.ParseOptions) => {
readonly _tag: "User";
readonly name: string;
readonly age: number;
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const User: Schema.Struct<{
_tag: Schema.PropertySignature<":", "User", never, "?:", "User" | undefined, true, never>;
} & {
name: typeof Schema.String;
age: typeof Schema.Number;
}>
User
)({
name: string
name
: "John",
age: number
age
: 44 }))
// Output: { _tag: 'User', name: 'John', age: 44 }

While a primary tag is often sufficient, TypeScript allows you to define multiple tags for more complex data structuring needs. Here’s an example demonstrating the use of multiple tags within a single struct:

Example (Adding Multiple Tags to a Struct)

This example defines a product schema with a primary tag ("Product") and an additional category tag ("Electronics"), adding further specificity to the data structure.

import {
import Schema
Schema
} from "effect"
const
const Product: Schema.TaggedStruct<"Product", {
category: Schema.tag<"Electronics">;
name: typeof Schema.String;
price: typeof Schema.Number;
}>
Product
=
import Schema
Schema
.
const TaggedStruct: <"Product", {
category: Schema.tag<"Electronics">;
name: typeof Schema.String;
price: typeof Schema.Number;
}>(value: "Product", fields: {
category: Schema.tag<"Electronics">;
name: typeof Schema.String;
price: typeof Schema.Number;
}) => Schema.TaggedStruct<...>

A tagged struct is a struct that has a tag property that is used to distinguish between different types of objects.

The tag is optional when using the make method.

@example

import { Schema } from "effect"
const User = Schema.TaggedStruct("User", {
name: Schema.String,
age: Schema.Number
})
assert.deepStrictEqual(User.make({ name: "John", age: 44 }), { _tag: "User", name: "John", age: 44 })

@since3.10.0

TaggedStruct
("Product", {
category: Schema.tag<"Electronics">
category
:
import Schema
Schema
.
const tag: <"Electronics">(tag: "Electronics") => Schema.tag<"Electronics">

Returns a property signature that represents a tag. A tag is a literal value that is used to distinguish between different types of objects. The tag is optional when using the make method.

@seeTaggedStruct

@example

import { Schema } from "effect"
const User = Schema.Struct({
_tag: Schema.tag("User"),
name: Schema.String,
age: Schema.Number
})
assert.deepStrictEqual(User.make({ name: "John", age: 44 }), { _tag: "User", name: "John", age: 44 })

@since3.10.0

tag
("Electronics"),
name: typeof Schema.String
name
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
price: typeof Schema.Number
price
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
// `_tag` and `category` are optional when creating an instance
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const Product: Schema.TaggedStruct<"Product", {
category: Schema.tag<"Electronics">;
name: typeof Schema.String;
price: typeof Schema.Number;
}>
Product
.
TypeLiteral<{ _tag: tag<"Product">; } & { category: tag<"Electronics">; name: typeof String$; price: typeof Number$; }, []>.make(props: {
readonly category?: "Electronics";
readonly name: string;
readonly price: number;
readonly _tag?: "Product";
}, options?: MakeOptions): {
readonly category: "Electronics";
readonly name: string;
readonly price: number;
readonly _tag: "Product";
}
make
({
name: string
name
: "Smartphone",
price: number
price
: 999 }))
/*
Output:
{
_tag: 'Product',
category: 'Electronics',
name: 'Smartphone',
price: 999
}
*/

When you need to define a schema for your custom data type defined through a class, the most convenient and fast way is to use the Schema.instanceOf constructor.

Example (Defining a Schema with instanceOf)

import {
import Schema
Schema
} from "effect"
class
class MyData
MyData
{
constructor(readonly
MyData.name: string
name
: string) {}
}
const
const MyDataSchema: Schema.instanceOf<MyData>
MyDataSchema
=
import Schema
Schema
.
const instanceOf: <typeof MyData>(constructor: typeof MyData, annotations?: Schema.Annotations.Schema<MyData, readonly []> | undefined) => Schema.instanceOf<MyData>

@since3.10.0

instanceOf
(
class MyData
MyData
)
// ┌─── MyData
// ▼
type
type Type = MyData
Type
= typeof
const MyDataSchema: Schema.instanceOf<MyData>
MyDataSchema
.
Schema<MyData, MyData, never>.Type: MyData
Type
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<MyData, MyData>(schema: Schema.Schema<MyData, MyData, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => MyData
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const MyDataSchema: Schema.instanceOf<MyData>
MyDataSchema
)(new
constructor MyData(name: string): MyData
MyData
("name")))
// Output: MyData { name: 'name' }
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<MyData, MyData>(schema: Schema.Schema<MyData, MyData, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => MyData
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const MyDataSchema: Schema.instanceOf<MyData>
MyDataSchema
)({
name: string
name
: "name" }))
/*
throws
ParseError: Expected MyData, actual {"name":"name"}
*/

The Schema.instanceOf constructor is just a lightweight wrapper of the Schema.declare API, which is the primitive in effect/Schema for declaring new custom data types.

However, note that Schema.instanceOf can only be used for classes that expose a public constructor. If you try to use it with classes that, for some reason, have marked the constructor as private, you’ll receive a TypeScript error:

Example (Error With Private Constructors)

import {
import Schema
Schema
} from "effect"
class
class MyData
MyData
{
static
MyData.make: (name: string) => MyData
make
= (
name: string
name
: string) => new
constructor MyData(name: string): MyData
MyData
(
name: string
name
)
private constructor(readonly
MyData.name: string
name
: string) {}
}
// @ts-expect-error
const
const MyDataSchema: Schema.instanceOf<any>
MyDataSchema
=
import Schema
Schema
.
const instanceOf: <abstract new (...args: any) => any>(constructor: abstract new (...args: any) => any, annotations?: Schema.Annotations.Schema<any, readonly []> | undefined) => Schema.instanceOf<any>

@since3.10.0

instanceOf
(
class MyData
MyData
)
/*
Argument of type 'typeof MyData' is not assignable to parameter of type 'abstract new (...args: any) => any'.
Cannot assign a 'private' constructor type to a 'public' constructor type.ts(2345)
*/

In such cases, you cannot use Schema.instanceOf, and you must rely on Schema.declare like this:

Example (Using Schema.declare With Private Constructors)

import {
import Schema
Schema
} from "effect"
class
class MyData
MyData
{
static
MyData.make: (name: string) => MyData
make
= (
name: string
name
: string) => new
constructor MyData(name: string): MyData
MyData
(
name: string
name
)
private constructor(readonly
MyData.name: string
name
: string) {}
}
const
const MyDataSchema: Schema.SchemaClass<MyData, MyData, never>
MyDataSchema
=
import Schema
Schema
.
const declare: <MyData>(is: (input: unknown) => input is MyData, annotations?: Schema.Annotations.Schema<MyData, readonly []> | undefined) => Schema.SchemaClass<MyData, MyData, never> (+1 overload)

The constraint R extends Schema.Context<P[number]> enforces dependencies solely from typeParameters. This ensures that when you call Schema.to or Schema.from, you receive a schema with a never context.

@since3.10.0

declare
(
(
input: unknown
input
: unknown):
input: unknown
input
is
class MyData
MyData
=>
input: unknown
input
instanceof
class MyData
MyData
).
Annotable<SchemaClass<MyData, MyData, never>, MyData, MyData, never>.annotations(annotations: Schema.Annotations.GenericSchema<MyData>): Schema.SchemaClass<MyData, MyData, never>

Merges a set of new annotations with existing ones, potentially overwriting any duplicates.

annotations
({
Annotations.Schema<MyData, readonly []>.identifier?: string
identifier
: "MyData" })
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<MyData, MyData>(schema: Schema.Schema<MyData, MyData, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => MyData
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const MyDataSchema: Schema.SchemaClass<MyData, MyData, never>
MyDataSchema
)(
class MyData
MyData
.
MyData.make: (name: string) => MyData
make
("name")))
// Output: MyData { name: 'name' }
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Schema
Schema
.
decodeUnknownSync<MyData, MyData>(schema: Schema.Schema<MyData, MyData, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => MyData
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const MyDataSchema: Schema.SchemaClass<MyData, MyData, never>
MyDataSchema
)({
name: string
name
: "name" }))
/*
throws
ParseError: Expected MyData, actual {"name":"name"}
*/

The pick static function available on each struct schema can be used to create a new Struct by selecting specific properties from an existing Struct.

Example (Picking Properties from a Struct)

import {
import Schema
Schema
} from "effect"
// Define a struct schema with properties "a", "b", and "c"
const
const MyStruct: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>
MyStruct
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
c: typeof Schema.Boolean
c
:
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
})
// Create a new schema that picks properties "a" and "c"
//
// ┌─── Struct<{
// | a: typeof Schema.String;
// | c: typeof Schema.Boolean;
// | }>
// ▼
const
const PickedSchema: Schema.Struct<{
a: typeof Schema.String;
c: typeof Schema.Boolean;
}>
PickedSchema
=
const MyStruct: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>
MyStruct
.
Struct<{ a: typeof String$; b: typeof Number$; c: typeof Boolean$; }>.pick<["a", "c"]>(keys_0: "a", keys_1: "c"): Schema.Struct<{
a: typeof Schema.String;
c: typeof Schema.Boolean;
}>
pick
("a", "c")

The Schema.pick function can be applied more broadly beyond just Struct types, such as with unions of schemas. However it returns a generic SchemaClass.

Example (Picking Properties from a Union)

import {
import Schema
Schema
} from "effect"
// Define a union of two struct schemas
const
const MyUnion: Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>
MyUnion
=
import Schema
Schema
.
function Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>(members_0: Schema.Struct<...>, members_1: Schema.Struct<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.String
b
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
c: typeof Schema.String
c
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
import Schema
Schema
.
function Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>(fields: {
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}): Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.Number
a
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
d: typeof Schema.Number
d
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// Create a new schema that picks properties "a" and "b"
//
// ┌─── SchemaClass<{
// | readonly a: string | number;
// | readonly b: string | number;
// | }>
// ▼
const
const PickedSchema: Schema.SchemaClass<{
readonly a: string | number;
readonly b: string | number;
}, {
readonly a: string | number;
readonly b: string | number;
}, never>
PickedSchema
=
const MyUnion: Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>
MyUnion
.
Pipeable.pipe<Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>, Schema.SchemaClass<...>>(this: Schema.Union<...>, ab: (_: Schema.Union<...>) => Schema.SchemaClass<...>): Schema.SchemaClass<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const pick: <{
readonly a: string;
readonly b: string;
readonly c: string;
} | {
readonly a: number;
readonly b: number;
readonly d: number;
}, {
readonly a: string;
readonly b: string;
readonly c: string;
} | {
...;
}, [...]>(keys_0: "a", keys_1: "b") => <R>(self: Schema.Schema<...>) => Schema.SchemaClass<...>

@since3.10.0

pick
("a", "b"))

The omit static function available in each struct schema can be used to create a new Struct by excluding particular properties from an existing Struct.

Example (Omitting Properties from a Struct)

import {
import Schema
Schema
} from "effect"
// Define a struct schema with properties "a", "b", and "c"
const
const MyStruct: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>
MyStruct
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
c: typeof Schema.Boolean
c
:
import Schema
Schema
.
class Boolean
export Boolean

@since3.10.0

Boolean
})
// Create a new schema that omits property "b"
//
// ┌─── Schema.Struct<{
// | a: typeof Schema.String;
// | c: typeof Schema.Boolean;
// | }>
// ▼
const
const PickedSchema: Schema.Struct<{
a: typeof Schema.String;
c: typeof Schema.Boolean;
}>
PickedSchema
=
const MyStruct: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
c: typeof Schema.Boolean;
}>
MyStruct
.
Struct<{ a: typeof String$; b: typeof Number$; c: typeof Boolean$; }>.omit<["b"]>(keys_0: "b"): Schema.Struct<{
a: typeof Schema.String;
c: typeof Schema.Boolean;
}>
omit
("b")

The Schema.omit function can be applied more broadly beyond just Struct types, such as with unions of schemas. However it returns a generic Schema.

Example (Omitting Properties from a Union)

import {
import Schema
Schema
} from "effect"
// Define a union of two struct schemas
const
const MyUnion: Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>
MyUnion
=
import Schema
Schema
.
function Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>(members_0: Schema.Struct<...>, members_1: Schema.Struct<...>): Schema.Union<...> (+3 overloads)

@since3.10.0

Union
(
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.String
b
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
c: typeof Schema.String
c
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
import Schema
Schema
.
function Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>(fields: {
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}): Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.Number
a
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
,
d: typeof Schema.Number
d
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
)
// Create a new schema that omits property "b"
//
// ┌─── SchemaClass<{
// | readonly a: string | number;
// | }>
// ▼
const
const PickedSchema: Schema.SchemaClass<{
readonly a: string | number;
}, {
readonly a: string | number;
}, never>
PickedSchema
=
const MyUnion: Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>
MyUnion
.
Pipeable.pipe<Schema.Union<[Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.String;
c: typeof Schema.String;
}>, Schema.Struct<{
a: typeof Schema.Number;
b: typeof Schema.Number;
d: typeof Schema.Number;
}>]>, Schema.SchemaClass<...>>(this: Schema.Union<...>, ab: (_: Schema.Union<...>) => Schema.SchemaClass<...>): Schema.SchemaClass<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const omit: <{
readonly a: string;
readonly b: string;
readonly c: string;
} | {
readonly a: number;
readonly b: number;
readonly d: number;
}, {
readonly a: string;
readonly b: string;
readonly c: string;
} | {
...;
}, [...]>(keys_0: "b") => <R>(self: Schema.Schema<...>) => Schema.SchemaClass<...>

@since3.10.0

omit
("b"))

The Schema.partial function makes all properties within a schema optional.

Example (Making All Properties Optional)

import {
import Schema
Schema
} from "effect"
// Create a schema with an optional property "a"
const
const schema: Schema.SchemaClass<{
readonly a?: string | undefined;
}, {
readonly a?: string | undefined;
}, never>
schema
=
import Schema
Schema
.
const partial: <{
readonly a: string;
}, {
readonly a: string;
}, never>(self: Schema.Schema<{
readonly a: string;
}, {
readonly a: string;
}, never>) => Schema.SchemaClass<{
readonly a?: string | undefined;
}, {
readonly a?: string | undefined;
}, never>

@since3.10.0

partial
(
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
}>(fields: {
a: typeof Schema.String;
}): Schema.Struct<{
a: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}))
// ┌─── { readonly a?: string | undefined; }
// ▼
type
type Type = {
readonly a?: string | undefined;
}
Type
= typeof
const schema: Schema.SchemaClass<{
readonly a?: string | undefined;
}, {
readonly a?: string | undefined;
}, never>
schema
.
Schema<{ readonly a?: string | undefined; }, { readonly a?: string | undefined; }, never>.Type: {
readonly a?: string | undefined;
}
Type

By default, the Schema.partial operation adds undefined to the type of each property. If you want to avoid this, you can use Schema.partialWith and pass { exact: true } as an argument.

Example (Defining an Exact Partial Schema)

import {
import Schema
Schema
} from "effect"
// Create a schema with an optional property "a" without allowing undefined
const
const schema: Schema.SchemaClass<{
readonly a?: string;
}, {
readonly a?: string;
}, never>
schema
=
import Schema
Schema
.
const partialWith: <{
readonly a: string;
}, {
readonly a: string;
}, never, {
readonly exact: true;
}>(self: Schema.Schema<{
readonly a: string;
}, {
readonly a: string;
}, never>, options: {
readonly exact: true;
}) => Schema.SchemaClass<...> (+1 overload)

@since3.10.0

partialWith
(
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
}>(fields: {
a: typeof Schema.String;
}): Schema.Struct<{
a: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
{
exact: true
exact
: true }
)
// ┌─── { readonly a?: string; }
// ▼
type
type Type = {
readonly a?: string;
}
Type
= typeof
const schema: Schema.SchemaClass<{
readonly a?: string;
}, {
readonly a?: string;
}, never>
schema
.
Schema<{ readonly a?: string; }, { readonly a?: string; }, never>.Type: {
readonly a?: string;
}
Type

The Schema.required function ensures that all properties in a schema are mandatory.

Example (Making All Properties Required)

import {
import Schema
Schema
} from "effect"
// Create a schema and make all properties required
const
const schema: Schema.SchemaClass<{
readonly a: string;
readonly b: number;
}, {
readonly a: string;
readonly b: number;
}, never>
schema
=
import Schema
Schema
.
const required: <{
readonly a?: string;
readonly b?: number;
}, {
readonly a?: string;
readonly b?: number;
}, never>(self: Schema.Schema<{
readonly a?: string;
readonly b?: number;
}, {
readonly a?: string;
readonly b?: number;
}, never>) => Schema.SchemaClass<...>

@since3.10.0

required
(
import Schema
Schema
.
function Struct<{
a: Schema.optionalWith<typeof Schema.String, {
exact: true;
}>;
b: Schema.optionalWith<typeof Schema.Number, {
exact: true;
}>;
}>(fields: {
a: Schema.optionalWith<typeof Schema.String, {
exact: true;
}>;
b: Schema.optionalWith<typeof Schema.Number, {
exact: true;
}>;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
a: Schema.optionalWith<typeof Schema.String, {
exact: true;
}>
a
:
import Schema
Schema
.
const optionalWith: <typeof Schema.String, {
exact: true;
}>(self: typeof Schema.String, options: {
exact: true;
}) => Schema.optionalWith<typeof Schema.String, {
exact: true;
}> (+1 overload)

@since3.10.0

optionalWith
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
, {
exact: true
exact
: true }),
b: Schema.optionalWith<typeof Schema.Number, {
exact: true;
}>
b
:
import Schema
Schema
.
const optionalWith: <typeof Schema.Number, {
exact: true;
}>(self: typeof Schema.Number, options: {
exact: true;
}) => Schema.optionalWith<typeof Schema.Number, {
exact: true;
}> (+1 overload)

@since3.10.0

optionalWith
(
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
, {
exact: true
exact
: true })
})
)
// ┌─── { readonly a: string; readonly b: number; }
// ▼
type
type Type = {
readonly a: string;
readonly b: number;
}
Type
= typeof
const schema: Schema.SchemaClass<{
readonly a: string;
readonly b: number;
}, {
readonly a: string;
readonly b: number;
}, never>
schema
.
Schema<{ readonly a: string; readonly b: number; }, { readonly a: string; readonly b: number; }, never>.Type: {
readonly a: string;
readonly b: number;
}
Type

In this example, both a and b are made required, even though they were initially defined as optional.

The Schema.keyof operation creates a schema that represents the keys of a given object schema.

Example (Extracting Keys from an Object Schema)

import {
import Schema
Schema
} from "effect"
const
const schema: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>
schema
=
import Schema
Schema
.
function Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>(fields: {
a: typeof Schema.String;
b: typeof Schema.Number;
}): Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}> (+1 overload)

@since3.10.0

Struct
({
a: typeof Schema.String
a
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
b: typeof Schema.Number
b
:
import Schema
Schema
.
class Number
export Number

@since3.10.0

Number
})
const
const keys: Schema.SchemaClass<"a" | "b", "a" | "b", never>
keys
=
import Schema
Schema
.
const keyof: <{
readonly a: string;
readonly b: number;
}, {
readonly a: string;
readonly b: number;
}, never>(self: Schema.Schema<{
readonly a: string;
readonly b: number;
}, {
readonly a: string;
readonly b: number;
}, never>) => Schema.SchemaClass<...>

@since3.10.0

keyof
(
const schema: Schema.Struct<{
a: typeof Schema.String;
b: typeof Schema.Number;
}>
schema
)
// ┌─── "a" | "b"
// ▼
type
type Type = "a" | "b"
Type
= typeof
const keys: Schema.SchemaClass<"a" | "b", "a" | "b", never>
keys
.
Schema<"a" | "b", "a" | "b", never>.Type: "a" | "b"
Type