LinkRepresents a single step in an Encoding chain.
Details
A link pairs a target AST with a Transformation or Middleware
that converts values between the current node and the target.
to— the AST node on the other side of this transformation step.transformation— the bidirectional conversion logic (decode/encode).
Links are composed into a non-empty array (Encoding) attached to AST nodes that have a different encoded representation.
export class class Linkclass Link {
to: AST;
transformation: SchemaTransformation.Transformation<any, any, any, any> | SchemaTransformation.Middleware<any, any, any, any, any, any>;
}
Represents a single step in an
Encoding
chain.
Details
A link pairs a target
AST
with a Transformation or Middleware
that converts values between the current node and the target.
to — the AST node on the other side of this transformation step.
transformation — the bidirectional conversion logic (decode/encode).
Links are composed into a non-empty array (
Encoding
) attached to
AST nodes that have a different encoded representation.
Link {
readonly Link.to: ASTto: type AST =
| Declaration
| Null
| Undefined
| Void
| Never
| Unknown
| Any
| String
| Number
| Boolean
| BigInt
| Symbol
| Literal
| UniqueSymbol
| ObjectKeyword
| Enum
| TemplateLiteral
| Arrays
| Objects
| Union<AST>
| Suspend
Discriminated union of all AST node types.
Details
Every Schema has an .ast property of this type. Use the guard functions
(
isString
,
isObjects
, etc.) to narrow to a specific variant,
then access variant-specific fields.
- All variants share the
Base
fields:
annotations, checks,
encoding, context.
- Discriminate on the
_tag field (e.g. "String", "Objects", "Union").
AST
readonly Link.transformation: SchemaTransformation.Transformation<any, any, any, any> | SchemaTransformation.Middleware<any, any, any, any, any, any>transformation:
| import SchemaTransformationSchemaTransformation.class Transformation<in out T, in out E, RD = never, RE = never>class Transformation {
_tag: 'Transformation';
decode: SchemaGetter.Getter<T, E, RD>;
encode: SchemaGetter.Getter<E, T, RE>;
flip: () => Transformation<E, T, RE, RD>;
compose: <T2, RD2, RE2>(other: Transformation<T2, T, RD2, RE2>) => Transformation<T2, E, RD | RD2, RE | RE2>;
}
Represents a bidirectional transformation between a decoded type T and an encoded
type E, built from a pair of Getters.
When to use
Use when you need a schema transformation that defines how a schema converts
between two representations.
- You want to compose multiple transformations into a pipeline.
- You want to flip a transformation to swap decode/encode.
Details
This is the primary building block for Schema.decodeTo, Schema.encodeTo,
Schema.decode, Schema.encode, and Schema.link. Each direction is a
SchemaGetter.Getter that handles optionality, failure, and Effect services.
- Immutable —
flip() and compose() return new instances.
flip() swaps the decode and encode getters.
compose(other) chains: this.decode then other.decode for decoding,
other.encode then this.encode for encoding.
Example (Composing two transformations)
import { SchemaTransformation } from "effect"
const trimAndLower = SchemaTransformation.trim().compose(
SchemaTransformation.toLowerCase()
)
// decode: trim then lowercase
// encode: passthrough (both directions)
Transformation<any, any, any, any>
| import SchemaTransformationSchemaTransformation.class Middleware<in out T, in out E, RDE, RDT, RET, REE>class Middleware {
_tag: 'Middleware';
decode: (effect: Effect.Effect<Option.Option<E>, SchemaIssue.Issue, RDE>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<T>, SchemaIssue.Issue, RDT>;
encode: (effect: Effect.Effect<Option.Option<T>, SchemaIssue.Issue, RET>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<E>, SchemaIssue.Issue, REE>;
flip: () => Middleware<E, T, RET, REE, RDE, RDT>;
}
Middleware that wraps the entire parsing Effect pipeline for both
decode and encode directions.
When to use
Use when you need a schema middleware to catch or recover from parsing
errors (e.g. Schema.catchDecoding), run side effects around the parsing
pipeline, or access the full Effect rather than a single decoded value.
Details
Unlike Transformation, which operates on individual values via Getter,
Middleware receives the full Effect produced by the inner schema and can
intercept, modify, retry, or replace it.
decode receives an Effect<Option<E>, Issue, RDE> and returns
Effect<Option<T>, Issue, RDT>.
encode receives an Effect<Option<T>, Issue, RET> and returns
Effect<Option<E>, Issue, REE>.
flip() swaps the decode and encode functions, producing a
Middleware<E, T, ...>.
Typically constructed indirectly via Schema.middlewareDecoding or
Schema.middlewareEncoding rather than instantiating this class directly.
Example (Creating a middleware that falls back on decode failure)
import { Effect, Option, SchemaTransformation } from "effect"
const fallback = new SchemaTransformation.Middleware(
(effect) => Effect.catch(effect, () => Effect.succeed(Option.some("fallback"))),
(effect) => effect
)
Middleware<any, any, any, any, any, any>
constructor(
to: ASTto: type AST =
| Declaration
| Null
| Undefined
| Void
| Never
| Unknown
| Any
| String
| Number
| Boolean
| BigInt
| Symbol
| Literal
| UniqueSymbol
| ObjectKeyword
| Enum
| TemplateLiteral
| Arrays
| Objects
| Union<AST>
| Suspend
Discriminated union of all AST node types.
Details
Every Schema has an .ast property of this type. Use the guard functions
(
isString
,
isObjects
, etc.) to narrow to a specific variant,
then access variant-specific fields.
- All variants share the
Base
fields:
annotations, checks,
encoding, context.
- Discriminate on the
_tag field (e.g. "String", "Objects", "Union").
AST,
transformation: | SchemaTransformation.Transformation<
any,
any,
any,
any
>
| SchemaTransformation.Middleware<
any,
any,
any,
any,
any,
any
>
transformation:
| import SchemaTransformationSchemaTransformation.class Transformation<in out T, in out E, RD = never, RE = never>class Transformation {
_tag: 'Transformation';
decode: SchemaGetter.Getter<T, E, RD>;
encode: SchemaGetter.Getter<E, T, RE>;
flip: () => Transformation<E, T, RE, RD>;
compose: <T2, RD2, RE2>(other: Transformation<T2, T, RD2, RE2>) => Transformation<T2, E, RD | RD2, RE | RE2>;
}
Represents a bidirectional transformation between a decoded type T and an encoded
type E, built from a pair of Getters.
When to use
Use when you need a schema transformation that defines how a schema converts
between two representations.
- You want to compose multiple transformations into a pipeline.
- You want to flip a transformation to swap decode/encode.
Details
This is the primary building block for Schema.decodeTo, Schema.encodeTo,
Schema.decode, Schema.encode, and Schema.link. Each direction is a
SchemaGetter.Getter that handles optionality, failure, and Effect services.
- Immutable —
flip() and compose() return new instances.
flip() swaps the decode and encode getters.
compose(other) chains: this.decode then other.decode for decoding,
other.encode then this.encode for encoding.
Example (Composing two transformations)
import { SchemaTransformation } from "effect"
const trimAndLower = SchemaTransformation.trim().compose(
SchemaTransformation.toLowerCase()
)
// decode: trim then lowercase
// encode: passthrough (both directions)
Transformation<any, any, any, any>
| import SchemaTransformationSchemaTransformation.class Middleware<in out T, in out E, RDE, RDT, RET, REE>class Middleware {
_tag: 'Middleware';
decode: (effect: Effect.Effect<Option.Option<E>, SchemaIssue.Issue, RDE>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<T>, SchemaIssue.Issue, RDT>;
encode: (effect: Effect.Effect<Option.Option<T>, SchemaIssue.Issue, RET>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<E>, SchemaIssue.Issue, REE>;
flip: () => Middleware<E, T, RET, REE, RDE, RDT>;
}
Middleware that wraps the entire parsing Effect pipeline for both
decode and encode directions.
When to use
Use when you need a schema middleware to catch or recover from parsing
errors (e.g. Schema.catchDecoding), run side effects around the parsing
pipeline, or access the full Effect rather than a single decoded value.
Details
Unlike Transformation, which operates on individual values via Getter,
Middleware receives the full Effect produced by the inner schema and can
intercept, modify, retry, or replace it.
decode receives an Effect<Option<E>, Issue, RDE> and returns
Effect<Option<T>, Issue, RDT>.
encode receives an Effect<Option<T>, Issue, RET> and returns
Effect<Option<E>, Issue, REE>.
flip() swaps the decode and encode functions, producing a
Middleware<E, T, ...>.
Typically constructed indirectly via Schema.middlewareDecoding or
Schema.middlewareEncoding rather than instantiating this class directly.
Example (Creating a middleware that falls back on decode failure)
import { Effect, Option, SchemaTransformation } from "effect"
const fallback = new SchemaTransformation.Middleware(
(effect) => Effect.catch(effect, () => Effect.succeed(Option.some("fallback"))),
(effect) => effect
)
Middleware<any, any, any, any, any, any>
) {
this.Link.to: ASTto = to: ASTto
this.Link.transformation: SchemaTransformation.Transformation<any, any, any, any> | SchemaTransformation.Middleware<any, any, any, any, any, any>transformation = transformation: | SchemaTransformation.Transformation<
any,
any,
any,
any
>
| SchemaTransformation.Middleware<
any,
any,
any,
any,
any,
any
>
transformation
}
}