suspend<S>Creates a suspended schema that defers evaluation until needed. This is essential for creating recursive schemas where a schema references itself, preventing infinite recursion during schema definition.
Example (Defining recursive tree schemas)
import { Schema } from "effect"
interface Tree {
readonly value: number
readonly children: ReadonlyArray<Tree>
}
const Tree = Schema.Struct({
value: Schema.Number,
children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
})export interface interface suspend<S extends Constraint>Creates a suspended schema that defers evaluation until needed. This is
essential for creating recursive schemas where a schema references itself,
preventing infinite recursion during schema definition.
Example (Defining recursive tree schemas)
import { Schema } from "effect"
interface Tree {
readonly value: number
readonly children: ReadonlyArray<Tree>
}
const Tree = Schema.Struct({
value: Schema.Number,
children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
})
Type-level representation returned by
suspend
.
suspend<function (type parameter) S in suspend<S extends Constraint>S extends Constraint> extends
interface BottomLazy<out Ast extends SchemaAST.AST, out Rebuild extends Top, in out TypeParameters extends ReadonlyArray<Constraint> = readonly [], out TypeMutability extends Mutability = "readonly", out TypeOptionality extends Optionality = "required", out TypeConstructorDefault extends ConstructorDefault = "no-default", out EncodedMutability extends Mutability = "readonly", out EncodedOptionality extends Optionality = "required">Lazy Bottom variant for schema implementations that compute their public
views on demand.
When to use
Use as an implementation base for schema interfaces that must expose
Bottom behavior without forcing TypeScript to eagerly evaluate expensive
Type, Encoded, or service views.
Details
The laziness is purely type-level; runtime behavior is unchanged.
BottomLazy keeps the structural operations inherited from Bottom, but
erases the expensive schema views to unknown. Concrete schema interfaces can
then redeclare the precise views they expose. This keeps wide schemas such as
Struct and Union cheaper when generic code reads a single view, while
preserving their exact public types.
BottomLazy<
import SchemaASTSchemaAST.class Suspendclass Suspend {
_tag: 'Suspend';
thunk: () => AST;
getParser: (recur: (ast: AST) => SchemaParser.Parser) => SchemaParser.Parser;
recur: (recur: (ast: AST) => AST) => Suspend;
getExpected: (getExpected: (ast: AST) => string) => string;
annotations: Schema.Annotations.Annotations | undefined;
checks: Checks | undefined;
encoding: Encoding | undefined;
context: Context | undefined;
toString: () => string;
}
AST node for lazy/recursive schemas.
Details
Wraps a thunk (() => AST) that is memoized on first call. Use this to
define recursive or mutually recursive schemas without infinite loops at
construction time.
Example (Defining recursive schema ASTs)
import { Schema, SchemaAST } from "effect"
interface Category {
readonly name: string
readonly children: ReadonlyArray<Category>
}
const Category = Schema.Struct({
name: Schema.String,
children: Schema.Array(Schema.suspend((): Schema.Codec<Category> => Category))
})
// The recursive branch is a Suspend node
Suspend,
interface suspend<S extends Constraint>Creates a suspended schema that defers evaluation until needed. This is
essential for creating recursive schemas where a schema references itself,
preventing infinite recursion during schema definition.
Example (Defining recursive tree schemas)
import { Schema } from "effect"
interface Tree {
readonly value: number
readonly children: ReadonlyArray<Tree>
}
const Tree = Schema.Struct({
value: Schema.Number,
children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
})
Type-level representation returned by
suspend
.
suspend<function (type parameter) S in suspend<S extends Constraint>S>,
function (type parameter) S in suspend<S extends Constraint>S["~type.parameters"],
function (type parameter) S in suspend<S extends Constraint>S["~type.mutability"],
function (type parameter) S in suspend<S extends Constraint>S["~type.optionality"],
function (type parameter) S in suspend<S extends Constraint>S["~type.constructor.default"],
function (type parameter) S in suspend<S extends Constraint>S["~encoded.mutability"],
function (type parameter) S in suspend<S extends Constraint>S["~encoded.optionality"]
>
{
readonly "Type": function (type parameter) S in suspend<S extends Constraint>S["Type"]
readonly "Encoded": function (type parameter) S in suspend<S extends Constraint>S["Encoded"]
readonly "DecodingServices": function (type parameter) S in suspend<S extends Constraint>S["DecodingServices"]
readonly "EncodingServices": function (type parameter) S in suspend<S extends Constraint>S["EncodingServices"]
readonly "~type.make.in": function (type parameter) S in suspend<S extends Constraint>S["~type.make.in"]
readonly "~type.make": function (type parameter) S in suspend<S extends Constraint>S["~type.make"]
readonly "Iso": function (type parameter) S in suspend<S extends Constraint>S["Iso"]
}
/**
* Creates a suspended schema that defers evaluation until needed. This is
* essential for creating recursive schemas where a schema references itself,
* preventing infinite recursion during schema definition.
*
* **Example** (Defining recursive tree schemas)
*
* ```ts
* import { Schema } from "effect"
*
* interface Tree {
* readonly value: number
* readonly children: ReadonlyArray<Tree>
* }
*
* const Tree = Schema.Struct({
* value: Schema.Number,
* children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
* })
* ```
*
* @category constructors
* @since 3.10.0
*/
export function function suspend<S extends Constraint>(
f: () => S
): suspend<S>
Creates a suspended schema that defers evaluation until needed. This is
essential for creating recursive schemas where a schema references itself,
preventing infinite recursion during schema definition.
Example (Defining recursive tree schemas)
import { Schema } from "effect"
interface Tree {
readonly value: number
readonly children: ReadonlyArray<Tree>
}
const Tree = Schema.Struct({
value: Schema.Number,
children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
})
suspend<function (type parameter) S in suspend<S extends Constraint>(f: () => S): suspend<S>S extends Constraint>(f: () => Sf: () => function (type parameter) S in suspend<S extends Constraint>(f: () => S): suspend<S>S): interface suspend<S extends Constraint>Creates a suspended schema that defers evaluation until needed. This is
essential for creating recursive schemas where a schema references itself,
preventing infinite recursion during schema definition.
Example (Defining recursive tree schemas)
import { Schema } from "effect"
interface Tree {
readonly value: number
readonly children: ReadonlyArray<Tree>
}
const Tree = Schema.Struct({
value: Schema.Number,
children: Schema.Array(Schema.suspend((): Schema.Codec<Tree> => Tree))
})
Type-level representation returned by
suspend
.
suspend<function (type parameter) S in suspend<S extends Constraint>(f: () => S): suspend<S>S> {
return const make: <S extends Constraint>(
ast: S["ast"],
options?: object
) => S
Creates a schema from an AST (Abstract Syntax Tree) node.
Details
This is the fundamental constructor for all schemas in the Effect Schema
library. It takes an AST node and wraps it in a fully-typed schema that
preserves all type information and provides the complete schema API.
The make function is used internally to create all primitive schemas like
String, Number, Boolean, etc., as well as more complex schemas. It's
the bridge between the untyped AST representation and the strongly-typed
schema.
make(new import SchemaASTSchemaAST.constructor Suspend(thunk: () => SchemaAST.AST, annotations?: Annotations.Annotations, checks?: SchemaAST.Checks, encoding?: SchemaAST.Encoding, context?: SchemaAST.Context): SchemaAST.SuspendAST node for lazy/recursive schemas.
Details
Wraps a thunk (() => AST) that is memoized on first call. Use this to
define recursive or mutually recursive schemas without infinite loops at
construction time.
Example (Defining recursive schema ASTs)
import { Schema, SchemaAST } from "effect"
interface Category {
readonly name: string
readonly children: ReadonlyArray<Category>
}
const Category = Schema.Struct({
name: Schema.String,
children: Schema.Array(Schema.suspend((): Schema.Codec<Category> => Category))
})
// The recursive branch is a Suspend node
Suspend(() => f: () => Sf().Constraint["ast"]: SchemaAST.ASTast))
}