Effect by Example: Parsing JSON with Schema

Tags:

schema

Effect has a powerful type validation library (like Zod) called Schema.

Basic Example

Here is a basic example:

import {
import Schema
Schema
} from "effect";
const
const testSchema: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
testSchema
=
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
,
});
const
const data: {
name: string;
age: number;
}
data
= {
name: string
name
: "Bob",
age: number
age
: 30,
};
const
const string: string
string
=
var JSON: JSON

An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

JSON
.
JSON.stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string (+1 overload)

Converts a JavaScript value to a JavaScript Object Notation (JSON) string.

@paramvalue A JavaScript value, usually an object or array, to be converted.

@paramreplacer A function that transforms the results.

@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.

stringify
(
const data: {
name: string;
age: number;
}
data
);
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 (+1 overload)

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
("string:",
const string: string
string
);
const
const decoded: {
readonly name: string;
readonly age: number;
}
decoded
=
import Schema
Schema
.
decodeUnknownSync<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, {
readonly name: string;
readonly age: number;
}, never>, options?: ParseOptions): (u: unknown, overrideOptions?: ParseOptions) => {
readonly name: string;
readonly age: number;
}
export decodeUnknownSync

@throwsParseError

@since3.10.0

decodeUnknownSync
(
const testSchema: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>
testSchema
)(
var JSON: JSON

An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

JSON
.
JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): any

Converts a JavaScript Object Notation (JSON) string into an object.

@paramtext A valid JSON string.

@paramreviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.

parse
(
const string: string
string
));
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 (+1 overload)

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
("decoded:",
const decoded: {
readonly name: string;
readonly age: number;
}
decoded
);
string: {"name":"Bob","age":30}
decoded: {
  name: "Bob",
  age: 30,
}

Here, the last line will throw if the validation fails.

Transformations

Schema’s superpower is its ability to describe two-way transformations.

The type of a Schema has two type parameters: the input type and the output type.

type
type Schema<Decoded, Encoded> = {}
Schema
<
function (type parameter) Decoded in type Schema<Decoded, Encoded>
Decoded
,
function (type parameter) Encoded in type Schema<Decoded, Encoded>
Encoded
> = {};

We can then use such a schema to transform between the two types.

Consider the Schema.parseJson function, which takes a schema and returns a new schema which transforms between JSON and the schema’s type.

Combined with other schemas, which can serialize/deserialize types that are not JSON-compatible, we can build a complex schema capable of encoding/decoding any type.

import {
import Schema
Schema
} from "effect";
const
const testSchema: Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>
testSchema
=
import Schema
Schema
.
function Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>(fields: {
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}): Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}> (+1 overload)

@since3.10.0

Struct
({
name: Schema.Set$<typeof Schema.String>
name
:
import Schema
Schema
.
Set<typeof Schema.String>(value: typeof Schema.String): Schema.Set$<typeof Schema.String>
export Set

@ignore

Set
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
),
age: typeof Schema.Date
age
:
import Schema
Schema
.
class Date
export Date

This schema converts a string into a Date object using the new Date constructor. It ensures that only valid date strings are accepted, rejecting any strings that would result in an invalid date, such as new Date("Invalid Date").

@since3.10.0

Date
,
});
const
const testSchemaJson: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>>
testSchemaJson
=
import Schema
Schema
.
const parseJson: <Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>>(schema: Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>, options?: Schema.ParseJsonOptions) => Schema.transform<...> (+1 overload)

The ParseJson combinator provides a method to convert JSON strings into the unknown type using the underlying functionality of JSON.parse. It also utilizes JSON.stringify for encoding.

You can optionally provide a ParseJsonOptions to configure both JSON.parse and JSON.stringify executions.

Optionally, you can pass a schema Schema<A, I, R> to obtain an A type instead of unknown.

@example

import * as assert from "node:assert"
import * as Schema from "effect/Schema"
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson())(`{"a":"1"}`), { a: "1" })
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson(Schema.Struct({ a: Schema.NumberFromString })))(`{"a":"1"}`), { a: 1 })

@since3.10.0

parseJson
(
const testSchema: Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>
testSchema
);
const
const data: {
name: Set<string>;
age: Date;
}
data
= {
name: Set<string>
name
: new
var Set: SetConstructor
new <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set
(["Bob", "Alice"]),
age: Date
age
: new
var Date: DateConstructor
new () => Date (+3 overloads)
Date
(),
};
const
const encoded: string
encoded
=
import Schema
Schema
.
encodeSync<{
readonly name: Set<string>;
readonly age: Date;
}, string>(schema: Schema.Schema<{
readonly name: Set<string>;
readonly age: Date;
}, string, never>, options?: ParseOptions): (a: {
readonly name: Set<string>;
readonly age: Date;
}, overrideOptions?: ParseOptions) => string
export encodeSync

@since3.10.0

encodeSync
(
const testSchemaJson: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>>
testSchemaJson
)(
const data: {
name: Set<string>;
age: Date;
}
data
);
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 (+1 overload)

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
("encoded:",
const encoded: string
encoded
);
const
const decoded: {
readonly name: Set<string>;
readonly age: Date;
}
decoded
=
import Schema
Schema
.
decodeSync<{
readonly name: Set<string>;
readonly age: Date;
}, string>(schema: Schema.Schema<{
readonly name: Set<string>;
readonly age: Date;
}, string, never>, options?: ParseOptions): (i: string, overrideOptions?: ParseOptions) => {
readonly name: Set<string>;
readonly age: Date;
}
export decodeSync

@since3.10.0

decodeSync
(
const testSchemaJson: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: Schema.Set$<typeof Schema.String>;
age: typeof Schema.Date;
}>>
testSchemaJson
)(
const encoded: string
encoded
);
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 (+1 overload)

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
("decoded:",
const decoded: {
readonly name: Set<string>;
readonly age: Date;
}
decoded
);
encoded: {"name":["Bob","Alice"],"age":"2025-07-14T06:58:45.906Z"}
decoded: {
  name: Set(2) {
    "Bob",
    "Alice",
  },
  age: 2025-07-14T06:58:45.906Z,
}

Consuming Schema from Effects

All of the examples so far on this page have been using the *Sync variants of the Schema functions. These all return synchronously, but throw if the validation fails, or a transformation is asynchronous.

To consume these apis as Effects, just drop the Sync suffix.

import {
import Schema
Schema
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect";
const
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>>
schema
=
import Schema
Schema
.
const parseJson: <Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>>(schema: Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>, options?: Schema.ParseJsonOptions) => Schema.transform<...> (+1 overload)

The ParseJson combinator provides a method to convert JSON strings into the unknown type using the underlying functionality of JSON.parse. It also utilizes JSON.stringify for encoding.

You can optionally provide a ParseJsonOptions to configure both JSON.parse and JSON.stringify executions.

Optionally, you can pass a schema Schema<A, I, R> to obtain an A type instead of unknown.

@example

import * as assert from "node:assert"
import * as Schema from "effect/Schema"
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson())(`{"a":"1"}`), { a: "1" })
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson(Schema.Struct({ a: Schema.NumberFromString })))(`{"a":"1"}`), { a: 1 })

@since3.10.0

parseJson
(
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
,
}),
);
const
const main: Effect.Effect<void, ParseError, never>
main
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<string, ParseError, never>> | YieldWrap<Effect.Effect<{
readonly name: string;
readonly age: number;
}, ParseError, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const data: {
name: string;
age: number;
}
data
= {
name: string
name
: "Bob",
age: number
age
: 30,
};
const
const encoded: string
encoded
= yield*
import Schema
Schema
.
const encode: <{
readonly name: string;
readonly age: number;
}, string, never>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, string, never>, options?: ParseOptions) => (a: {
readonly name: string;
readonly age: number;
}, overrideOptions?: ParseOptions) => Effect.Effect<...>

@since3.10.0

encode
(
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>>
schema
)(
const data: {
name: string;
age: number;
}
data
);
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 (+1 overload)

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
("encoded:",
const encoded: string
encoded
);
const
const decoded: {
readonly name: string;
readonly age: number;
}
decoded
= yield*
import Schema
Schema
.
const decode: <{
readonly name: string;
readonly age: number;
}, string, never>(schema: Schema.Schema<{
readonly name: string;
readonly age: number;
}, string, never>, options?: ParseOptions) => (i: string, overrideOptions?: ParseOptions) => Effect.Effect<...>

@since3.10.0

decode
(
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
name: typeof Schema.String;
age: typeof Schema.Number;
}>>
schema
)(
const encoded: string
encoded
);
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 (+1 overload)

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
("decoded:",
const decoded: {
readonly name: string;
readonly age: number;
}
decoded
);
});
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runSync: <void, ParseError>(effect: Effect.Effect<void, ParseError, never>) => void

Executes an effect synchronously, running it immediately and returning the result.

Details

This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling.

Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects.

When to Use

Use this function when:

  • You are sure that the effect will not fail or involve asynchronous operations.
  • You need a direct, synchronous result from the effect.
  • You are working within a context where asynchronous effects are not allowed.

Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using

runPromise

or

runSyncExit

.

Example (Synchronous Logging)

import { Effect } from "effect"
const program = Effect.sync(() => {
console.log("Hello, World!")
return 1
})
const result = Effect.runSync(program)
// Output: Hello, World!
console.log(result)
// Output: 1

Example (Incorrect Usage with Failing or Async Effects)

import { Effect } from "effect"
try {
// Attempt to run an effect that fails
Effect.runSync(Effect.fail("my error"))
} catch (e) {
console.error(e)
}
// Output:
// (FiberFailure) Error: my error
try {
// Attempt to run an effect that involves async work
Effect.runSync(Effect.promise(() => Promise.resolve(1)))
} catch (e) {
console.error(e)
}
// Output:
// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work

@seerunSyncExit for a version that returns an Exit type instead of throwing an error.

@since2.0.0

runSync
(
const main: Effect.Effect<void, ParseError, never>
main
);
encoded: {"name":"Bob","age":30}
decoded: {
  name: "Bob",
  age: 30,
}

Different field names when encoding/decoding to/from JSON

import {
import Schema
Schema
,
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
} from "effect";
const
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>>
schema
=
import Schema
Schema
.
const parseJson: <Schema.Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>>(schema: Schema.Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>, options?: Schema.ParseJsonOptions) => Schema.transform<...> (+1 overload)

The ParseJson combinator provides a method to convert JSON strings into the unknown type using the underlying functionality of JSON.parse. It also utilizes JSON.stringify for encoding.

You can optionally provide a ParseJsonOptions to configure both JSON.parse and JSON.stringify executions.

Optionally, you can pass a schema Schema<A, I, R> to obtain an A type instead of unknown.

@example

import * as assert from "node:assert"
import * as Schema from "effect/Schema"
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson())(`{"a":"1"}`), { a: "1" })
assert.deepStrictEqual(Schema.decodeUnknownSync(Schema.parseJson(Schema.Struct({ a: Schema.NumberFromString })))(`{"a":"1"}`), { a: 1 })

@since3.10.0

parseJson
(
import Schema
Schema
.
function Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>(fields: {
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}): Schema.Struct<...> (+1 overload)

@since3.10.0

Struct
({
type CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>
CamelCase
:
import Schema
Schema
.
const propertySignature: <typeof Schema.String>(self: typeof Schema.String) => Schema.propertySignature<typeof Schema.String>

Lifts a Schema into a PropertySignature.

@since3.10.0

propertySignature
(
import Schema
Schema
.
class String
export String

@since3.10.0

String
).
Pipeable.pipe<Schema.propertySignature<typeof Schema.String>, Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>>(this: Schema.propertySignature<...>, ab: (_: Schema.propertySignature<typeof Schema.String>) => Schema.PropertySignature<...>): Schema.PropertySignature<...> (+21 overloads)
pipe
(
import Schema
Schema
.
const fromKey: <"snake_case">(key: "snake_case") => <TypeToken, Type, EncodedToken, Encoded, HasDefault, R>(self: Schema.PropertySignature<TypeToken, Type, ... 4 more ..., R>) => Schema.PropertySignature<...> (+1 overload)

Enhances a property signature by specifying a different key for it in the Encoded type.

@since3.10.0

fromKey
("snake_case"),
),
}),
);
const
const data: {
CamelCase: string;
}
data
= {
type CamelCase: string
CamelCase
: "hi",
};
const
const encoded: string
encoded
=
import Schema
Schema
.
encodeSync<{
readonly CamelCase: string;
}, string>(schema: Schema.Schema<{
readonly CamelCase: string;
}, string, never>, options?: ParseOptions): (a: {
readonly CamelCase: string;
}, overrideOptions?: ParseOptions) => string
export encodeSync

@since3.10.0

encodeSync
(
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>>
schema
)(
const data: {
CamelCase: string;
}
data
);
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 (+1 overload)

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
("encoded:",
const encoded: string
encoded
);
const
const decoded: {
readonly CamelCase: string;
}
decoded
=
import Schema
Schema
.
decodeSync<{
readonly CamelCase: string;
}, string>(schema: Schema.Schema<{
readonly CamelCase: string;
}, string, never>, options?: ParseOptions): (i: string, overrideOptions?: ParseOptions) => {
readonly CamelCase: string;
}
export decodeSync

@since3.10.0

decodeSync
(
const schema: Schema.transform<Schema.SchemaClass<unknown, string, never>, Schema.Struct<{
CamelCase: Schema.PropertySignature<":", string, "snake_case", ":", string, false, never>;
}>>
schema
)(
const encoded: string
encoded
);
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 (+1 overload)

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
("decoded:",
const decoded: {
readonly CamelCase: string;
}
decoded
);
encoded: {"snake_case":"hi"}
decoded: {
  CamelCase: "hi",
}