Skip to content
Effect Days 2026 Get your ticket

SchemaGetter

Builds one-way conversions used by schemas.

A Getter<T, E, R> receives an optional encoded value and returns an optional decoded value. It can also report a schema issue or require Effect services. Schema transformations use getters to describe one direction of a conversion, for example decoding a field from input data. This module includes basic getters, validation helpers, pure and effectful conversions, and ready-made conversions for common string, number, binary, date, form, and URL-related values.

52 exports Added in v4.0.0 Source

Combining

joinKeyValue

Added in v4.0.0 Source

Joins a record of key-value pairs into a delimited string.

When to use

Use when you need a schema getter to serialize a present decoded record as a delimited key-value string.

Details

The getter is pure and never fails. It joins entries with separator (default ,) and joins each key and value with keyValueSeparator (default =).

See

Signature

declare function joinKeyValue<E extends Record<PropertyKey, string>>(options?: {
readonly keyValueSeparator?: string;
readonly separator?: string;
}): Getter<string, E>

Example

(Joining key-value records)

import { Effect, Option, SchemaGetter } from "effect"
const join = SchemaGetter.joinKeyValue()
await Effect.runPromise(join.run(Option.some({ a: "1", b: "2" }), {})) // => Option.some("a=1,b=2")

Constructors

fail

Added in v4.0.0 Source

Creates a getter that always fails with the given issue.

When to use

Use when you need a schema getter that unconditionally rejects input.

  • Building custom validation getters that produce specific error types.

Details

  • Always fails with the Issue returned by f.
  • The failure function receives the original Option<E> input and the effective ParseOptions for error context.

See

  • forbidden for a convenience helper for Forbidden issues
  • checkEffect to fail conditionally based on input value

Signature

declare function fail<T, E>(f: (oe: Option<E>, options: ParseOptions) => Issue): Getter<T, E>

Example

(Defining an always-failing getter)

import { Effect, Option, SchemaGetter, SchemaIssue } from "effect"
const rejectAll = SchemaGetter.fail<string, string>(
() => new SchemaIssue.InvalidValue({ message: "not allowed" })
)
const issue = await Effect.runPromise(Effect.flip(rejectAll.run(Option.some("x"), {})))
issue._tag // => "InvalidValue"

forbidden

Added in v4.0.0 Source

Creates a getter that always fails with a Forbidden issue.

When to use

Use when you need a schema getter to disallow a field or direction (encode/decode) entirely.

  • You want a clear "forbidden" error message in schema validation output.

Details

  • Always fails with SchemaIssue.Forbidden.
  • The message function receives the Option<E> input for context.

See

  • fail to fail with a custom issue type

Signature

declare function forbidden<T, E>(message: (oe: Option<E>) => string): Getter<T, E>

Example

(Forbidding a decode direction)

import { Effect, Option, SchemaGetter } from "effect"
const noEncode = SchemaGetter.forbidden<string, number>(
() => "encoding is not supported"
)
const issue = await Effect.runPromise(Effect.flip(noEncode.run(Option.some(1), {})))
issue._tag // => "Forbidden"

Builds a nested tree object from a list of bracket-path entries.

When to use

Use when you need a schema getter to parse FormData or URLSearchParams entries into structured objects.

  • You have flat key-value pairs with bracket-path keys that need nesting.

Details

  • A bracket path is a string like "user[address][city]" that describes nested object/array structure.
  • Interprets bracket paths and constructs the corresponding nested object.
  • Builds and returns a nested object from the input entries.
  • Supported syntax:
    • "foo" → object key "foo"
    • "foo[bar]" → nested { foo: { bar: ... } }
    • "foo[0]" → array index { foo: [value] }
    • "foo[]" → append to array foo
    • "" → real empty key
  • Duplicate keys for the same path are merged into arrays.
  • If a structural path conflicts with a previous leaf or a different container type, the later structural path replaces the conflicting value.
  • The notation has no escaping for ., [ or ], so keys containing these delimiters cannot be round-tripped without changing their structure.

See

Signature

declare function makeTreeRecord<A>(bracketPathEntries: readonly Array<readonly [string, A]>): TreeRecord<A>

Example

(Building a tree from bracket paths)

import { SchemaGetter } from "effect"
SchemaGetter.makeTreeRecord([
["user[name]", "Alice"],
["user[tags][]", "admin"],
["user[tags][]", "editor"]
]) // => { user: { name: "Alice", tags: ["admin", "editor"] } }

passthrough

Added in v4.0.0 Source

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.

See

Signature

declare function passthrough<T, E>(options: {
readonly strict: false;
}): Getter<T, E>
declare function passthrough<T>(): Getter<T, T>

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()
})
)
Schema.decodeSync(StringToString)("hello") // => "hello"

Returns the identity getter, typed for when the encoded type E is a subtype of T.

When to use

Use when you need a schema getter that passes values through without { strict: false } for an encoded type that narrows the decoded type.

Details

  • Same singleton as passthrough — no allocation, optimized in composition.

See

Signature

declare function passthroughSubtype<T, E>(): Getter<T, E>

Example

(Passing through subtypes)

import { Effect, Option, SchemaGetter } from "effect"
// "hello" extends string, so E extends T
const g = SchemaGetter.passthroughSubtype<string, "hello">()
await Effect.runPromise(g.run(Option.some("hello"), {})) // => Option.some("hello")

Returns the identity getter typed for the relationship T extends E.

When to use

Use when you need a schema getter that passes values through when the decoded/output type is narrower than the encoded/input type.

Details

  • Same singleton as passthrough — no allocation, optimized in composition.

See

Signature

declare function passthroughSupertype<T, E>(): Getter<T, E>

Example

(Passing through supertypes)

import { Effect, Option, SchemaGetter } from "effect"
// string extends string, so this is valid
const g = SchemaGetter.passthroughSupertype<string, string>()
await Effect.runPromise(g.run(Option.some("hello"), {})) // => Option.some("hello")

succeed

Added in v4.0.0 Source

Creates a getter that always produces the given constant value, ignoring the input.

When to use

Use when you need a schema getter that always decodes a field to a fixed value.

Details

The getter is pure and always returns Option.some(t) regardless of whether the input is Some or None.

See

Signature

declare function succeed<T, E>(t: T): Getter<T, E>

Example

(Returning a constant getter)

import { Effect, Option, SchemaGetter } from "effect"
const alwaysZero = SchemaGetter.succeed(0)
await Effect.runPromise(alwaysZero.run(Option.none(), {})) // => Option.some(0)

Converting

BigInt

Added in v4.0.0 Source

Coerces a value to bigint using the global BigInt() constructor.

When to use

Use when you need a schema getter to convert a present string, number, or boolean value to bigint.

Details

  • Delegates to globalThis.BigInt.
  • Throws at runtime if the input cannot be converted (e.g. non-numeric string).

Signature

declare function BigInt<E extends string | number | bigint | boolean>(): Getter<bigint, E>

Example

(Coercing to a bigint)

import { Effect, Option, SchemaGetter } from "effect"
const toBigInt = SchemaGetter.BigInt<string>()
await Effect.runPromise(toBigInt.run(Option.some("42"), {})) // => Option.some(42n)

Boolean

Added in v4.0.0 Source

Coerces any value to a boolean using the global Boolean() constructor.

When to use

Use when you need a schema getter to coerce a present encoded value to a boolean with Boolean().

Details

The getter is pure, never fails, and delegates to globalThis.Boolean.

Signature

declare function Boolean<E>(): Getter<boolean, E>

Example

(Coercing to a boolean)

import { Effect, Option, SchemaGetter } from "effect"
const toBool = SchemaGetter.Boolean<string>()
await Effect.runPromise(toBool.run(Option.some("true"), {})) // => Option.some(true)

Flattens a nested object into bracket-path entries, filtering leaf values by a type guard.

When to use

Use when you need a schema getter to serialize structured objects to flat key-value entries.

  • Building custom FormData or URLSearchParams encoders.

Details

  • Takes a nested object and produces flat [bracketPath, value] pairs suitable for FormData or URLSearchParams.
  • Returns a curried function: first call provides the leaf type guard, second call provides the object.
  • Recursively traverses objects and arrays.
  • If all elements of an array are leaves, encodes them as multiple entries with the same key (e.g. tags=a&tags=b). Otherwise uses indexed bracket paths (e.g. items[0], items[1]).
  • Non-leaf values that aren't objects or arrays are silently skipped.
  • Empty arrays and objects produce no entries, and path delimiters in property names are not escaped. The resulting format is therefore lossy.

See

Signature

declare function collectBracketPathEntries<A>(isLeaf: (value: unknown) => value is A): (input: object) => Array<[bracketPath: string, value: A]>

Example

(Flattening an object to bracket paths)

import { Predicate, SchemaGetter } from "effect"
const collectStrings = SchemaGetter.collectBracketPathEntries(Predicate.isString)
const entries = collectStrings({ user: { name: "Alice", tags: ["admin", "editor"] } })
entries // => [["user[name]", "Alice"], ["user[tags]", "admin"], ["user[tags]", "editor"]]

Date

Added in v4.0.0 Source

Coerces a value to a Date using new Date(input).

When to use

Use when you need a schema getter to coerce a present string, number, or existing date object into a new date object.

Details

  • Delegates to new globalThis.Date(input).
  • Does not validate the result — may produce an invalid Date.

See

Signature

declare function Date<E extends string | number | Date>(): Getter<Date, E>

Example

(Coercing to a Date)

import { Effect, Option, SchemaGetter } from "effect"
const toDate = SchemaGetter.Date<string>()
const result = await Effect.runPromise(toDate.run(Option.some("1970-01-01"), {}))
Option.map(result, (date) => date.toISOString()) // => Option.some("1970-01-01T00:00:00.000Z")

Parses a DateTime.Input value into a DateTime.Utc.

When to use

Use when you need a schema getter to decode a present encoded date/time value to a DateTime.Utc.

Details

  • Accepted input includes existing DateTime values, partial date/time parts, instant objects, zoned instant objects, JavaScript Date instances, epoch milliseconds, and date strings.
  • Converts successfully parsed values to UTC.
  • Fails with SchemaIssue.InvalidValue if the input cannot be parsed as a valid DateTime.

See

  • Date for a simpler coercion to Date (no validation)

Signature

declare function dateTimeUtcFromInput<E extends Input>(): Getter<Utc, E>

Example

(Parsing DateTime)

import { DateTime, Effect, Option, SchemaGetter } from "effect"
const parseDate = SchemaGetter.dateTimeUtcFromInput<string>()
const result = await Effect.runPromise(parseDate.run(Option.some("2024-01-01T00:00:00Z"), {}))
Option.map(result, DateTime.toEpochMillis) // => Option.some(1704067200000)

Number

Added in v4.0.0 Source

Coerces any value to a number using the global Number() constructor.

When to use

Use when you need a schema getter to coerce a present encoded value to a number with Number().

Details

The getter is pure, never fails, and delegates to globalThis.Number. It may produce NaN for non-numeric inputs.

See

Signature

declare function Number<E>(): Getter<number, E>

Example

(Coercing to a number)

import { Effect, Option, SchemaGetter } from "effect"
const toNumber = SchemaGetter.Number<string>()
await Effect.runPromise(toNumber.run(Option.some("42"), {})) // => Option.some(42)

String

Added in v4.0.0 Source

Coerces any value to a string using the global String() constructor.

When to use

Use when you need a schema getter to coerce a present encoded value to a string with String().

Details

The getter is pure, never fails, and delegates to globalThis.String.

See

Signature

declare function String<E>(): Getter<string, E>

Example

(Coercing to a string)

import { Effect, Option, SchemaGetter } from "effect"
const toString = SchemaGetter.String<number>()
await Effect.runPromise(toString.run(Option.some(42), {})) // => Option.some("42")

Decoding

decodeBase64

Added in v4.0.0 Source

Decodes a Base64 string to a Uint8Array.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid Base64.

See

Signature

declare function decodeBase64<E extends string>(): Getter<Uint8Array<ArrayBufferLike>, E>

Example

(Decoding Base64 to bytes)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeBase64<string>()
const result = await Effect.runPromise(decode.run(Option.some("AQID"), {}))
Option.map(result, Array.from) // => Option.some([1, 2, 3])

Decodes a Base64 string to a UTF-8 string.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid Base64.

See

Signature

declare function decodeBase64String<E extends string>(): Getter<string, E>

Example

(Decoding Base64 to string)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeBase64String<string>()
await Effect.runPromise(decode.run(Option.some("aGVsbG8="), {})) // => Option.some("hello")

Decodes a URL-safe Base64 string to a Uint8Array.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid Base64Url.

See

Signature

declare function decodeBase64Url<E extends string>(): Getter<Uint8Array<ArrayBufferLike>, E>

Example

(Decoding Base64Url to bytes)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeBase64Url<string>()
const result = await Effect.runPromise(decode.run(Option.some("-_8="), {}))
Option.map(result, Array.from) // => Option.some([251, 255])

Decodes a URL-safe Base64 string to a UTF-8 string.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid Base64Url.

See

Signature

declare function decodeBase64UrlString<E extends string>(): Getter<string, E>

Example

(Decoding Base64Url to string)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeBase64UrlString<string>()
await Effect.runPromise(decode.run(Option.some("aGVsbG8"), {})) // => Option.some("hello")

Decodes a FormData object into a nested tree structure using bracket-path notation.

When to use

Use when you need a schema getter to parse FormData from HTTP requests into structured objects.

Details

The getter is pure and never fails. It interprets bracket-path keys such as user[name] and items[0] to build nested objects or arrays, and each leaf value is a string or Blob.

See

Signature

declare function decodeFormData(): Getter<TreeRecord<string | Blob>, FormData>

Example

(Decoding FormData)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeFormData()
const formData = new FormData()
formData.append("user[name]", "Alice")
await Effect.runPromise(decode.run(Option.some(formData), {})) // => Option.some({ user: { name: "Alice" } })

decodeHex

Added in v4.0.0 Source

Decodes a hexadecimal string to a Uint8Array.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid hex.

See

Signature

declare function decodeHex<E extends string>(): Getter<Uint8Array<ArrayBufferLike>, E>

Example

(Decoding hex to bytes)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeHex<string>()
const result = await Effect.runPromise(decode.run(Option.some("010203"), {}))
Option.map(result, Array.from) // => Option.some([1, 2, 3])

Decodes a hexadecimal string to a UTF-8 string.

Details

  • Fails with SchemaIssue.InvalidValue if the input is not valid hex.

See

Signature

declare function decodeHexString<E extends string>(): Getter<string, E>

Example

(Decoding hex to string)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeHexString<string>()
await Effect.runPromise(decode.run(Option.some("68656c6c6f"), {})) // => Option.some("hello")

Decodes a URI component encoded string using decodeURIComponent.

Details

  • Fails with SchemaIssue.InvalidValue if the input contains malformed percent-encoding sequences.

See

Signature

declare function decodeUriComponent<E extends string>(): Getter<string, E>

Example

(Decoding a URI component)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeUriComponent<string>()
await Effect.runPromise(decode.run(Option.some("hello%20world"), {})) // => Option.some("hello world")

Decodes a URLSearchParams object into a nested tree structure using bracket-path notation.

When to use

Use when you need a schema getter to parse query parameters from URLs into structured objects.

Details

The getter is pure and never fails. It interprets bracket-path keys such as user[name] and items[0] to build nested objects or arrays, and each leaf value is a string.

See

Signature

declare function decodeURLSearchParams(): Getter<TreeRecord<string>, URLSearchParams>

Example

(Decoding URLSearchParams)

import { Effect, Option, SchemaGetter } from "effect"
const decode = SchemaGetter.decodeURLSearchParams()
const params = new URLSearchParams("user[name]=Alice")
await Effect.runPromise(decode.run(Option.some(params), {})) // => Option.some({ user: { name: "Alice" } })

parseJson

Added in v4.0.0 Source

Parses a JSON string into a value.

When to use

Use when you need a schema getter to parse a present encoded JSON string during decoding.

Details

  • Skips None inputs.
  • Without reviver: returns Schema.MutableJson (typed JSON).
  • With reviver: returns unknown (reviver may produce arbitrary values).
  • On parse failure, fails with SchemaIssue.InvalidValue whose expected annotation is "a valid JSON string". Its default message includes the reported input when reportInput is enabled.

See

Signature

declare function parseJson<E extends string>(): Getter<MutableJson, E>
declare function parseJson<E extends string>(options: ParseJsonOptions): Getter<unknown, E>

Example

(Parsing JSON)

import { Effect, Option, SchemaGetter } from "effect"
const parse = SchemaGetter.parseJson<string>()
await Effect.runPromise(parse.run(Option.some("{\"a\":1}"), {})) // => Option.some({ a: 1 })

Encoding

encodeBase64

Added in v4.0.0 Source

Encodes a Uint8Array or string to a Base64 string.

Details

The getter is pure and never fails.

See

Signature

declare function encodeBase64<E extends string | Uint8Array<ArrayBufferLike>>(): Getter<string, E>

Example

(Encoding to Base64)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeBase64<Uint8Array>()
await Effect.runPromise(encode.run(Option.some(new Uint8Array([1, 2, 3])), {})) // => Option.some("AQID")

Encodes a Uint8Array or string to a URL-safe Base64 string.

Details

The getter is pure and never fails.

See

Signature

declare function encodeBase64Url<E extends string | Uint8Array<ArrayBufferLike>>(): Getter<string, E>

Example

(Encoding to Base64Url)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeBase64Url<Uint8Array>()
await Effect.runPromise(encode.run(Option.some(new Uint8Array([251, 255])), {})) // => Option.some("-_8")

Encodes a nested object into a FormData instance using bracket-path notation.

When to use

Use when you need a schema getter to serialize structured data to FormData for HTTP requests.

Details

The getter is pure and never fails. It flattens nested objects or arrays into bracket-path keys such as user[name] and items[0]. Non-object inputs produce an empty FormData.

See

Signature

declare function encodeFormData(): Getter<FormData, unknown>

Example

(Encoding to FormData)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeFormData()
const result = await Effect.runPromise(encode.run(Option.some({ name: "Alice" }), {}))
Option.map(result, (formData) => formData.get("name")) // => Option.some("Alice")

encodeHex

Added in v4.0.0 Source

Encodes a Uint8Array or string to a hexadecimal string.

Details

The getter is pure and never fails.

See

Signature

declare function encodeHex<E extends string | Uint8Array<ArrayBufferLike>>(): Getter<string, E>

Example

(Encoding to hex)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeHex<Uint8Array>()
await Effect.runPromise(encode.run(Option.some(new Uint8Array([1, 2, 3])), {})) // => Option.some("010203")

Encodes a present string using encodeURIComponent.

Details

  • Skips None inputs.
  • May throw a URIError for malformed surrogate pairs; this exception is not converted into an Issue.

See

Signature

declare function encodeUriComponent<E extends string>(): Getter<string, E>

Example

(Encoding a URI component)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeUriComponent<string>()
await Effect.runPromise(encode.run(Option.some("hello world"), {})) // => Option.some("hello%20world")

Encodes a nested object into a URLSearchParams instance using bracket-path notation.

When to use

Use when you need a schema getter to serialize structured data to query parameters for URLs.

Details

The getter is pure and never fails. It flattens nested objects or arrays into bracket-path keys. Non-object inputs produce an empty URLSearchParams.

See

Signature

declare function encodeURLSearchParams(): Getter<URLSearchParams, unknown>

Example

(Encoding to URLSearchParams)

import { Effect, Option, SchemaGetter } from "effect"
const encode = SchemaGetter.encodeURLSearchParams()
const result = await Effect.runPromise(encode.run(Option.some({ name: "Alice" }), {}))
Option.map(result, (params) => params.toString()) // => Option.some("name=Alice")

Stringifies a present value using JSON.stringify.

When to use

Use when you need a schema getter to serialize a present decoded value to JSON text during encoding.

Details

  • Skips None inputs.
  • If JSON.stringify throws or returns undefined, fails with SchemaIssue.InvalidValue.
  • Supports optional replacer and space options, matching JSON.stringify.

See

Signature

declare function stringifyJson(options?: StringifyJsonOptions): Getter<string, unknown>

Example

(Stringifying JSON)

import { Effect, Option, SchemaGetter } from "effect"
const stringify = SchemaGetter.stringifyJson()
await Effect.runPromise(stringify.run(Option.some({ a: 1 }), {})) // => Option.some("{\"a\":1}")

Filtering

omit

Added in v4.0.0 Source

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.

See

Signature

declare function omit<T>(): Getter<never, T>

Example

(Omitting a field during encoding)

import { Effect, Option, SchemaGetter } from "effect"
const omitField = SchemaGetter.omit<string>()
await Effect.runPromise(omitField.run(Option.some("hidden"), {})) // => Option.none()

Models

Getter

Added in v4.0.0 Source

Represents a composable transformation from an encoded type E to a decoded type T.

When to use

Use when you need a schema getter to build and compose custom transformations for Schema.decodeTo or Schema.decode.

Details

A getter wraps a function Option<E> -> Effect<Option<T>, Issue, R>. It receives Option.None when the encoded key is absent, such as a missing struct field, and returns Option.None to omit the value from the decoded output. It fails with Issue on invalid input and may require Effect services via R. .map(f) applies f to the decoded value inside Some while leaving None unchanged. .compose(other) chains two getters by feeding the output of this into other; passthrough getters on either side are optimized away.

See

Signature

declare class Getter<out T, in E, R = never> extends Class {
constructor<out T, in E, R = never>(run: (input: Option<E>, options: ParseOptions) => Effect<Option<T>, Issue, R>);
readonly run: (input: Option<E>, options: ParseOptions) => Effect<Option<T>, Issue, R>;
compose<T2, R2>(other: Getter<T2, T, R2>): Getter<T2, E, R | R2>;
map<T2>(f: (t: T) => T2): Getter<T2, E, R>;
}

Example

(Creating and composing getters)

import { Effect, Option, SchemaGetter } from "effect"
const parseNumber = SchemaGetter.transform<number, string>((s) => Number(s))
const double = SchemaGetter.transform<number, number>((n) => n * 2)
const composed = parseNumber.compose(double)
await Effect.runPromise(composed.run(Option.some("21"), {})) // => Option.some(42)

Splitting

split

Added in v4.0.0 Source

Splits a string into an array of strings by a separator.

When to use

Use when you need a schema getter to split a present encoded string containing a delimited list, such as CSV values.

Details

The getter is pure and never fails. It splits by separator (default ,). An empty string produces an empty array, not [""].

See

Signature

declare function split<E extends string>(options?: {
readonly separator?: string;
}): Getter<readonly Array<string>, E>

Example

(Splitting a comma-separated string)

import { Effect, Option, SchemaGetter } from "effect"
const splitComma = SchemaGetter.split<string>()
await Effect.runPromise(splitComma.run(Option.some("a,b,c"), {})) // => Option.some(["a", "b", "c"])

Parses a string into a record of key-value pairs.

When to use

Use when you need a schema getter to parse a present encoded string that contains delimited key-value pairs (e.g. "a=1,b=2").

Details

The getter is pure and never fails. It splits the string by separator (default ,) and then each pair by keyValueSeparator (default =). Pairs missing a key or value are silently skipped.

See

Signature

declare function splitKeyValue<E extends string>(options?: {
readonly keyValueSeparator?: string;
readonly separator?: string;
}): Getter<Record<string, string>, E>

Example

(Parsing a key-value string)

import { Effect, Option, SchemaGetter } from "effect"
const parse = SchemaGetter.splitKeyValue<string>()
await Effect.runPromise(parse.run(Option.some("a=1,b=2"), {})) // => Option.some({ a: "1", b: "2" })

Transforming

camelToSnake

Added in v4.0.0 Source

Converts a camelCase string to snake_case.

Details

  • Pure, delegates to String.camelToSnake.

See

Signature

declare function camelToSnake<E extends string>(): Getter<string, E>

Example

(Converting camel case to snake case)

import { Effect, Option, SchemaGetter } from "effect"
const toSnake = SchemaGetter.camelToSnake<string>()
await Effect.runPromise(toSnake.run(Option.some("userName"), {})) // => Option.some("user_name")

capitalize

Added in v4.0.0 Source

Capitalizes the first character of a string.

Details

  • Pure, delegates to String.capitalize.

Signature

declare function capitalize<E extends string>(): Getter<string, E>

Example

(Capitalizing a string)

import { Effect, Option, SchemaGetter } from "effect"
const cap = SchemaGetter.capitalize<string>()
await Effect.runPromise(cap.run(Option.some("hello"), {})) // => Option.some("Hello")

onNone

Added in v4.0.0 Source

Creates a getter that handles the case when the input is absent (Option.None).

When to use

Use when you need a schema getter to provide a fallback or computed value for missing struct keys.

  • Building custom "default value" logic more complex than withDefault.

Details

  • When input is None, calls f to produce the result.
  • When input is Some, passes it through unchanged.
  • f receives the parse options and may return None to keep the value absent.

See

  • required when absent input should fail
  • withDefault for a simpler default value for undefined inputs
  • onSome to handle only present values

Signature

declare function onNone<T, E = T, R = never>(f: (options: ParseOptions) => Effect<Option<T>, Issue, R>): Getter<T, E, R>

Example

(Providing a default timestamp for a missing field)

import { Effect, Option, SchemaGetter } from "effect"
const withTimestamp = SchemaGetter.onNone<number>(() =>
Effect.succeed(Option.some(0))
)
await Effect.runPromise(withTimestamp.run(Option.none(), {})) // => Option.some(0)

onSome

Added in v4.0.0 Source

Creates a getter that handles present values (Option.Some), passing None through.

When to use

Use when you need a schema getter to transform or validate only when a field value is present.

  • Missing keys should remain absent in the output.

Details

  • When input is None, returns None (no-op).
  • When input is Some(e), calls f(e, options) to produce the result.
  • f may return None to omit the value, or fail with an Issue.

See

  • onNone to handle only absent values
  • transform for a simpler pure transformation of present values
  • transformOrFail for fallible transformation of present values

Signature

declare function onSome<T, E, R = never>(f: (e: E, options: ParseOptions) => Effect<Option<T>, Issue, R>): Getter<T, E, R>

Example

(Transforming only present values)

import { Effect, Option, SchemaGetter } from "effect"
const parseIfPresent = SchemaGetter.onSome<number, string>(
(s) => Effect.succeed(Option.some(Number(s)))
)
await Effect.runPromise(parseIfPresent.run(Option.some("42"), {})) // => Option.some(42)

snakeToCamel

Added in v4.0.0 Source

Converts a snake_case string to camelCase.

Details

  • Pure, delegates to String.snakeToCamel.

See

Signature

declare function snakeToCamel<E extends string>(): Getter<string, E>

Example

(Converting snake case to camel case)

import { Effect, Option, SchemaGetter } from "effect"
const toCamel = SchemaGetter.snakeToCamel<string>()
await Effect.runPromise(toCamel.run(Option.some("user_name"), {})) // => Option.some("userName")

toLowerCase

Added in v4.0.0 Source

Converts a string to lowercase.

Details

  • Pure, delegates to String.toLowerCase.

See

Signature

declare function toLowerCase<E extends string>(): Getter<string, E>

Example

(Converting to lowercase)

import { Effect, Option, SchemaGetter } from "effect"
const lower = SchemaGetter.toLowerCase<string>()
await Effect.runPromise(lower.run(Option.some("HELLO"), {})) // => Option.some("hello")

toUpperCase

Added in v4.0.0 Source

Converts a string to uppercase.

Details

  • Pure, delegates to String.toUpperCase.

See

Signature

declare function toUpperCase<E extends string>(): Getter<string, E>

Example

(Converting to uppercase)

import { Effect, Option, SchemaGetter } from "effect"
const upper = SchemaGetter.toUpperCase<string>()
await Effect.runPromise(upper.run(Option.some("hello"), {})) // => Option.some("HELLO")

transform

Added in v4.0.0 Source

Creates a getter that applies a pure function to present values.

When to use

Use when you need a schema getter for a pure, infallible transformation between types.

  • Building encode/decode pairs for Schema.decodeTo.

Details

  • This is the most commonly used constructor.
  • Transforms Some(e) to Some(f(e)) and leaves None unchanged.
  • Skips None inputs — only called when a value is present.
  • Never fails.

See

Signature

declare function transform<T, E>(f: (e: E) => T): Getter<T, E>

Example

(Transforming strings to numbers)

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))
})
)
Schema.decodeSync(NumberFromString)("42") // => 42

Creates a getter that transforms the full Option — both present and absent values.

When to use

Use when you need a schema getter to handle both Some and None cases.

Details

The getter is pure and never fails. It receives the full Option<E> and must return Option<T>, so it can turn a present value into absent or an absent value into present.

See

  • transform when you only need to transform present values
  • omit when you always want None

Signature

declare function transformOptional<T, E>(f: (oe: Option<E>) => Option<T>): Getter<T, E>

Example

(Filtering out empty strings)

import { Effect, Option, SchemaGetter } from "effect"
const skipEmpty = SchemaGetter.transformOptional<string, string>((o) =>
Option.filter(o, (s) => s.length > 0)
)
await Effect.runPromise(skipEmpty.run(Option.some(""), {})) // => Option.none()

Creates a getter that applies a fallible, effectful transformation to present values.

When to use

Use when you need a schema getter for a transformation that may fail, require Effect services, or run asynchronously.

Details

  • Skips None inputs — only called when a value is present.
  • On success, wraps the result in Some.
  • On failure, propagates the Issue.

See

  • transform when transformation cannot fail
  • onSome when you need full Option control over the output

Signature

declare function transformOrFail<T, E, R = never>(f: (e: E, options: ParseOptions) => Effect<T, Issue, R>): Getter<T, E, R>

Example

(Parsing with failure)

import { Effect, Option, SchemaGetter, SchemaIssue } from "effect"
const safeParseInt = SchemaGetter.transformOrFail<number, string>(
(s, options) => {
const n = parseInt(s, 10)
return isNaN(n)
? Effect.fail(new SchemaIssue.InvalidValue({ message: "not an integer" }, s, options))
: Effect.succeed(n)
}
)
await Effect.runPromise(safeParseInt.run(Option.some("42"), {})) // => Option.some(42)

trim

Added in v4.0.0 Source

Strips whitespace from both ends of a string.

Details

  • Pure, delegates to String.trim.

Signature

declare function trim<E extends string>(): Getter<string, E>

Example

(Trimming whitespace)

import { Effect, Option, SchemaGetter } from "effect"
const trimmed = SchemaGetter.trim<string>()
await Effect.runPromise(trimmed.run(Option.some(" hello "), {})) // => Option.some("hello")

uncapitalize

Added in v4.0.0 Source

Uncapitalizes the first character of a string.

Details

  • Pure, delegates to String.uncapitalize.

Signature

declare function uncapitalize<E extends string>(): Getter<string, E>

Example

(Uncapitalizing a string)

import { Effect, Option, SchemaGetter } from "effect"
const uncap = SchemaGetter.uncapitalize<string>()
await Effect.runPromise(uncap.run(Option.some("Hello"), {})) // => Option.some("hello")

withDefault

Added in v4.0.0 Source

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.

See

  • onNone to handle only absent keys (not undefined values)
  • required when absent input should fail instead of using a default

Signature

declare function withDefault<T, R = never>(defaultValue: Effect<T, Issue, R>): Getter<T, T | undefined, R>

Example

(Providing a default value for an optional field)

import { Effect, Option, SchemaGetter } from "effect"
const withZero = SchemaGetter.withDefault(Effect.succeed(0))
await Effect.runPromise(withZero.run(Option.some(undefined), {})) // => Option.some(0)

Utility Types

JsonReplacer type

Added in v4.0.0 Source

Replacer function or property allowlist accepted by JSON.stringify.

Signature

type JsonReplacer = (this: any, key: string, value: any) => any | Array<string | number> | null

Validation

checkEffect

Added in v4.0.0 Source

Creates a getter that validates a value using an effectful check function.

When to use

Use when you need a schema getter to validate a decoded value (e.g. check a constraint or call an external service).

  • The validation may be asynchronous or require Effect services.

Details

  • Only runs when input is SomeNone passes through.
  • The check function returns a validation result:
    • undefined or true — value is valid, passes through.
    • false or a string — value is invalid, fails with an Issue.
    • An Issue object — fails with that issue directly.
    • { path, issue } — fails with a nested path issue (issue may be a message string or a full SchemaIssue.Issue).
  • Does not transform the value — input and output types are the same.

See

  • transform when you need to change the value, not just validate
  • fail for unconditional failure

Signature

declare function checkEffect<T, R = never>(f: (input: T, options: ParseOptions) => Effect<boolean | FilterIssue | undefined, never, R>): Getter<T, T, R>

Example

(Validating effectfully)

import { Effect, Option, SchemaGetter } from "effect"
const nonNegative = SchemaGetter.checkEffect<number>((n) =>
Effect.succeed(n >= 0 ? undefined : "must be non-negative")
)
await Effect.runPromise(nonNegative.run(Option.some(1), {})) // => Option.some(1)

required

Added in v4.0.0 Source

Creates a getter that fails with MissingKey if the input is absent (Option.None).

When to use

Use when you need a schema getter to require a struct field in the encoded input and report a missing key error when it is absent.

Details

  • When input is None, fails with SchemaIssue.MissingKey.
  • When input is Some, passes it through unchanged.
  • Optional annotations customize the error message for the missing key.

See

  • onNone to provide a fallback instead of failing
  • withDefault to substitute a default for undefined values

Signature

declare function required<T, E = T>(annotations?: Key<T>): Getter<T, E>

Example

(Defining a required struct field)

import { Effect, Option, SchemaGetter } from "effect"
const mustExist = SchemaGetter.required<string>()
const issue = await Effect.runPromise(Effect.flip(mustExist.run(Option.none(), {})))
issue._tag // => "MissingKey"