withDecodingDefault<S, R>Wraps the Encoded side with optional (key absent or undefined)
and provides a default Encoded value when the field is missing or
undefined during decoding.
When to use
Use when the default is expressed in the encoded representation, before the field's decoding transformation runs.
Details
The default value is specified in terms of the Encoded type (before any
decoding transformations).
Options:
encodingStrategy:"passthrough"(default): include the value in the encoded output."omit": omit the key from the encoded output.
Example (Providing a default for an optional field value)
import { Effect, Schema } from "effect"
const MySchema = Schema.Struct({
name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
})
const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
// result: { name: "anonymous" }export interface interface withDecodingDefault<S extends Constraint, R = never>Wraps the Encoded side with optional (key absent or undefined)
and provides a default Encoded value when the field is missing or
undefined during decoding.
When to use
Use when the default is expressed in the encoded representation, before the
field's decoding transformation runs.
Details
The default value is specified in terms of the Encoded type (before any
decoding transformations).
Options:
encodingStrategy:
"passthrough" (default): include the value in the encoded output.
"omit": omit the key from the encoded output.
Example (Providing a default for an optional field value)
import { Effect, Schema } from "effect"
const MySchema = Schema.Struct({
name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
})
const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
// result: { name: "anonymous" }
Type-level representation returned by
withDecodingDefault
.
withDecodingDefault<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>S extends Constraint, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>R = never> extends interface decodeTo<To extends Constraint, From extends Constraint, RD = never, RE = never>Creates a schema that transforms from a source schema to a target schema.
When to use
Use when decoding should change the schema's decoded type or encoded shape,
with an optional custom bidirectional transformation.
Details
Call it with the target schema to and then pipe the source schema from
into the returned function. The resulting schema decodes from
From["Encoded"] to To["Type"] and encodes from To["Type"] back to
From["Encoded"].
When no transformation is provided, SchemaTransformation.passthrough() is
used, so From["Type"] must already be compatible with To["Encoded"].
The resulting schema combines decoding and encoding services from both
schemas and any custom transformation.
Gotchas
In a custom transformation, decode maps From["Type"] to To["Encoded"]
and is used on the encoding path, while encode maps To["Encoded"] to
From["Type"] and is used on the decoding path.
Example (Transforming strings to numbers with a schema transformation)
import { Schema, SchemaGetter } from "effect"
const NumberFromString = Schema.String.pipe(
Schema.decodeTo(
Schema.Number,
{
decode: SchemaGetter.transform((s) => Number(s)),
encode: SchemaGetter.transform((n) => String(n))
}
)
)
const result = Schema.decodeUnknownSync(NumberFromString)("123")
// result: 123
Type-level representation returned by
decodeTo
.
decodeTo<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>S, interface optional<S extends Constraint>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.
Details
The resulting property may be absent or explicitly set to undefined.
Equivalent to optionalKey(UndefinedOr(S)).
Use
optionalKey
instead if you want exact optional semantics (absent
only, not undefined).
Example (Defining an optional field accepting undefined)
import { Schema } from "effect"
const schema = Schema.Struct({
name: Schema.String,
age: Schema.optional(Schema.Number)
})
// { readonly name: string; readonly age?: number | undefined }
type Person = typeof schema.Type
optional<interface toEncoded<S extends Constraint>Type-level representation returned by
toEncoded
.
Extracts the encoded-side schema: sets Type to equal the Encoded,
discarding the decoding transformation path.
toEncoded<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>S>>, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>R> {
readonly "Rebuild": interface withDecodingDefault<S extends Constraint, R = never>Wraps the Encoded side with optional (key absent or undefined)
and provides a default Encoded value when the field is missing or
undefined during decoding.
When to use
Use when the default is expressed in the encoded representation, before the
field's decoding transformation runs.
Details
The default value is specified in terms of the Encoded type (before any
decoding transformations).
Options:
encodingStrategy:
"passthrough" (default): include the value in the encoded output.
"omit": omit the key from the encoded output.
Example (Providing a default for an optional field value)
import { Effect, Schema } from "effect"
const MySchema = Schema.Struct({
name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
})
const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
// result: { name: "anonymous" }
Type-level representation returned by
withDecodingDefault
.
withDecodingDefault<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>S, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>R>
}
/**
* Wraps the `Encoded` side with `optional` (key absent **or** `undefined`)
* and provides a default `Encoded` value when the field is missing or
* `undefined` during decoding.
*
* **When to use**
*
* Use when the default is expressed in the encoded representation, before the
* field's decoding transformation runs.
*
* **Details**
*
* The default value is specified in terms of the `Encoded` type (before any
* decoding transformations).
*
* Options:
*
* - `encodingStrategy`:
* - `"passthrough"` (default): include the value in the encoded output.
* - `"omit"`: omit the key from the encoded output.
*
* **Example** (Providing a default for an optional field value)
*
* ```ts
* import { Effect, Schema } from "effect"
*
* const MySchema = Schema.Struct({
* name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
* })
*
* const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
* // result: { name: "anonymous" }
* ```
*
* @see {@link withDecodingDefaultKey} for the key-level variant (key absent only, not `undefined`)
* @see {@link withDecodingDefaultType} for the variant where the default is a `Type` value
* @category decoding
* @since 3.10.0
*/
export function function withDecodingDefault<
S extends Constraint,
R = never
>(
defaultValue: Effect.Effect<
S["Encoded"],
SchemaError,
R
>,
options?: DecodingDefaultOptions
): (self: S) => withDecodingDefault<S, R>
Wraps the Encoded side with optional (key absent or undefined)
and provides a default Encoded value when the field is missing or
undefined during decoding.
When to use
Use when the default is expressed in the encoded representation, before the
field's decoding transformation runs.
Details
The default value is specified in terms of the Encoded type (before any
decoding transformations).
Options:
encodingStrategy:
"passthrough" (default): include the value in the encoded output.
"omit": omit the key from the encoded output.
Example (Providing a default for an optional field value)
import { Effect, Schema } from "effect"
const MySchema = Schema.Struct({
name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
})
const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
// result: { name: "anonymous" }
withDecodingDefault<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>S extends Constraint, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>R = never>(
defaultValue: Effect.Effect<
S["Encoded"],
SchemaError,
R
>
(parameter) defaultValue: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
defaultValue: import EffectEffect.type Effect.Effect = /*unresolved*/ anyEffect<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>S["Encoded"], class SchemaErrorclass SchemaError {
message: string;
toString: () => string;
name: string;
stack: string;
cause: unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toJSON: () => unknown;
_tag: Tag;
issue: SchemaIssue.Issue;
}
Error thrown (or returned as the error channel value) when schema decoding
or encoding fails.
Details
The issue field contains a structured
Issue
tree describing
every validation failure, including the path to the problematic value,
expected types, and actual values received. message renders the issue tree
as a human-readable string.
Use
isSchemaError
to narrow an unknown value to SchemaError.
Example (Catching a SchemaError)
import { Schema } from "effect"
try {
Schema.decodeUnknownSync(Schema.Number)("not a number")
} catch (err) {
if (Schema.isSchemaError(err)) {
console.log(err.message)
// Expected number, actual "not a number"
}
}
SchemaError, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>R>,
options: DecodingDefaultOptionsoptions?: type DecodingDefaultOptions = {
readonly encodingStrategy?:
| "omit"
| "passthrough"
| undefined
}
Options for
withDecodingDefaultKey
and
withDecodingDefault
.
Details
encodingStrategy:
"passthrough" (default): pass the value through during encoding
"omit": omit the key from the encoded output
DecodingDefaultOptions
) {
const const encode: SchemaGetter.Getter<
unknown,
unknown,
never
>
const encode: {
run: (input: Option.Option<E>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<T>, SchemaIssue.Issue, R>;
map: (f: (t: unknown) => T2) => SchemaGetter.Getter<T2, unknown, never>;
compose: (other: SchemaGetter.Getter<T2, unknown, R2>) => SchemaGetter.Getter<T2, unknown, R2>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
encode = options: DecodingDefaultOptionsoptions?.encodingStrategy?: "omit" | "passthrough" | undefinedencodingStrategy === "omit" ? import SchemaGetterSchemaGetter.function omit<T>(): Getter<never, T>Creates a getter that always returns None, effectively omitting the value from output.
When to use
Use when you need a schema getter to exclude a field during decoding or
encoding.
Details
- Always returns
Option.None regardless of input.
- Never fails.
Example (Omitting a field during encoding)
import { SchemaGetter } from "effect"
const omitField = SchemaGetter.omit<string>()
omit() : import SchemaGetterSchemaGetter.function passthrough<unknown>(): SchemaGetter.Getter<unknown, unknown, never> (+1 overload)Returns the identity getter — passes the value through unchanged.
When to use
Use when you need a schema getter for one side of a decodeTo pair, either
encode or decode, to pass values through unchanged.
Details
- Pure, no allocation (singleton instance).
- Optimized away during
.compose() — composing with a passthrough is free.
- The default overload requires
T === E. Pass { strict: false } to opt
out of the type constraint.
Example (Passing through identity transformations)
import { Schema, SchemaGetter } from "effect"
// No transformation needed — types already match
const StringToString = Schema.String.pipe(
Schema.decodeTo(Schema.String, {
decode: SchemaGetter.passthrough(),
encode: SchemaGetter.passthrough()
})
)
passthrough()
return (self: S extends Constraintself: function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>S): interface withDecodingDefault<S extends Constraint, R = never>Wraps the Encoded side with optional (key absent or undefined)
and provides a default Encoded value when the field is missing or
undefined during decoding.
When to use
Use when the default is expressed in the encoded representation, before the
field's decoding transformation runs.
Details
The default value is specified in terms of the Encoded type (before any
decoding transformations).
Options:
encodingStrategy:
"passthrough" (default): include the value in the encoded output.
"omit": omit the key from the encoded output.
Example (Providing a default for an optional field value)
import { Effect, Schema } from "effect"
const MySchema = Schema.Struct({
name: Schema.String.pipe(Schema.optional, Schema.withDecodingDefault(Effect.succeed("anonymous")))
})
const result = Schema.decodeUnknownSync(MySchema)({ name: undefined })
// result: { name: "anonymous" }
Type-level representation returned by
withDecodingDefault
.
withDecodingDefault<function (type parameter) S in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>S, function (type parameter) R in withDecodingDefault<S extends Constraint, R = never>(defaultValue: Effect.Effect<S["Encoded"], SchemaError, R>, options?: DecodingDefaultOptions): (self: S) => withDecodingDefault<S, R>R> => {
return const optional: optionalLambda
<toEncoded<S>>(self: toEncoded<S>) => optional<toEncoded<S>>
Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.
Details
The resulting property may be absent or explicitly set to undefined.
Equivalent to optionalKey(UndefinedOr(S)).
Use
optionalKey
instead if you want exact optional semantics (absent
only, not undefined).
Example (Defining an optional field accepting undefined)
import { Schema } from "effect"
const schema = Schema.Struct({
name: Schema.String,
age: Schema.optional(Schema.Number)
})
// { readonly name: string; readonly age?: number | undefined }
type Person = typeof schema.Type
optional(const toEncoded: toEncodedLambda
;<S>(self: S) => toEncoded<S>
Type-level representation returned by
toEncoded
.
Extracts the encoded-side schema: sets Type to equal the Encoded,
discarding the decoding transformation path.
toEncoded(self: S extends Constraintself)).pipe(function decodeTo<S, Constraint, never, never>(to: S, transformation: {
readonly decode: SchemaGetter.Getter<NoInfer<S["Encoded"]>, unknown, never>;
readonly encode: SchemaGetter.Getter<unknown, NoInfer<S["Encoded"]>, never>;
}): (from: Constraint) => decodeTo<S, Constraint, never, never> (+1 overload)
Creates a schema that transforms from a source schema to a target schema.
When to use
Use when decoding should change the schema's decoded type or encoded shape,
with an optional custom bidirectional transformation.
Details
Call it with the target schema to and then pipe the source schema from
into the returned function. The resulting schema decodes from
From["Encoded"] to To["Type"] and encodes from To["Type"] back to
From["Encoded"].
When no transformation is provided, SchemaTransformation.passthrough() is
used, so From["Type"] must already be compatible with To["Encoded"].
The resulting schema combines decoding and encoding services from both
schemas and any custom transformation.
Gotchas
In a custom transformation, decode maps From["Type"] to To["Encoded"]
and is used on the encoding path, while encode maps To["Encoded"] to
From["Type"] and is used on the decoding path.
Example (Transforming strings to numbers with a schema transformation)
import { Schema, SchemaGetter } from "effect"
const NumberFromString = Schema.String.pipe(
Schema.decodeTo(
Schema.Number,
{
decode: SchemaGetter.transform((s) => Number(s)),
encode: SchemaGetter.transform((n) => String(n))
}
)
)
const result = Schema.decodeUnknownSync(NumberFromString)("123")
// result: 123
decodeTo(self: S extends Constraintself, {
decode: SchemaGetter.Getter<
S["Encoded"],
S["Encoded"] | undefined,
R
>
(property) decode: {
run: (input: Option.Option<E>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<T>, SchemaIssue.Issue, R>;
map: (f: (t: S['Encoded']) => T2) => SchemaGetter.Getter<T2, S['Encoded'] | undefined, R>;
compose: (other: SchemaGetter.Getter<T2, S['Encoded'], R2>) => SchemaGetter.Getter<T2, S['Encoded'] | undefined, R | R2>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
decode: import SchemaGetterSchemaGetter.function withDefault<T, R = never>(
defaultValue: Effect.Effect<
T,
SchemaIssue.Issue,
R
>
): Getter<T, T | undefined, R>
Creates a getter that replaces undefined values with a default.
When to use
Use when you need a schema getter to provide a fallback for a field that may
be undefined in the encoded input.
Details
- If the input is
Some(undefined) or None, produces Some(T).
- If the input is
Some(value) where value is not undefined, passes it through.
defaultValue is an Effect that will be executed each time a default is needed.
Example (Providing a default value for an optional field)
import { Effect, SchemaGetter } from "effect"
const withZero = SchemaGetter.withDefault(Effect.succeed(0))
// Getter<number, number | undefined>
withDefault(function toIssueEffect<A, R>(
self: Effect.Effect<A, SchemaError, R>
): Effect.Effect<A, SchemaIssue.Issue, R>
toIssueEffect(defaultValue: Effect.Effect<
S["Encoded"],
SchemaError,
R
>
(parameter) defaultValue: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
defaultValue)),
encode: SchemaGetter.Getter<
unknown,
unknown,
never
>
(property) encode: {
run: (input: Option.Option<E>, options: SchemaAST.ParseOptions) => Effect.Effect<Option.Option<T>, SchemaIssue.Issue, R>;
map: (f: (t: unknown) => T2) => SchemaGetter.Getter<T2, unknown, never>;
compose: (other: SchemaGetter.Getter<T2, unknown, R2>) => SchemaGetter.Getter<T2, unknown, R2>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
encode
}))
}
}