SchemaTransformation
Builds two-way conversions used by schemas.
A Transformation<T, E> describes how to decode an encoded value into a decoded value and how to encode it back again. Schema APIs use transformations to connect two representations, such as a string and a number, a JSON value and a richer TypeScript value, or a form field and an application value. This module includes transformation and middleware types, constructors for pure or effectful conversions, and common conversions used by the Schema module.
Constructors
Signature
declare function make<T, E, RD = never, RE = never>(options: {
readonly decode: Getter<T, E, RD>;
readonly encode: Getter<E, T, RE>;
}): Transformation<T, E, RD, RE>;passthrough
Transforms values by returning the input unchanged in both directions.
When to use
Use when you need a schema transformation to connect two schemas that share the same type with no actual conversion.
Details
- Both decode and encode are no-ops. - Returns a shared singleton instance (no allocation per call). - By default, T and E must be the same type. Pass { strict: false } to bypass the type constraint.
See
Signature
declare function passthrough<T, E>(options: { readonly strict: false }): Transformation<T, E>;
declare function passthrough<T>(): Transformation<T, T>;passthroughSubtype
Transforms values without changing them, typed so that E extends T — the encoded type is a subtype of the decoded type.
When to use
Use when you need a no-op schema transformation whose encoded side is more specific than its decoded side.
Details
- Both decode and encode are no-ops (same as passthrough). - Returns a shared singleton instance.
See
Signature
declare function passthroughSubtype<T, E>(): Transformation<T, E>;passthroughSupertype
Transforms values without changing them, typed so that T extends E, where the decoded type T is a subtype of the encoded type E.
When to use
Use when you need a no-op schema transformation whose decoded side is narrower than the encoded side.
Details
Both decode and encode are no-ops and return a shared singleton transformation.
See
Signature
declare function passthroughSupertype<T, E>(): Transformation<T, E>;Converting
bigintFromString
Decodes a string into a bigint and encodes a bigint back to a string.
When to use
Use when you need a schema transformation to parse large integer strings (e.g. database IDs, blockchain values).
Details
Decoding coerces the string to a bigint like BigInt(s). Encoding coerces the bigint to a string like String(n). Decoding fails if the string is not a valid bigint representation.
See
Signature
declare const bigintFromString: Transformation<bigint, string, never, never>;dateFromMillis
Decodes epoch milliseconds into a Date and encodes a Date back to epoch milliseconds.
When to use
Use when you need a schema transformation for numeric timestamps represented as milliseconds since the Unix epoch.
Details
Decoding creates a Date from the number like new Date(ms). Encoding returns the Date timestamp like date.getTime().
Gotchas
This transformation does not validate date validity. NaN, Infinity, and -Infinity decode to invalid Date instances.
See
dateFromStringSchemaGetter.dateTimeUtcFromInput
Signature
declare const dateFromMillis: Transformation<globalThis.Date, number>;dateFromString
Decodes a string into a Date and encodes a Date back to a string.
When to use
Use when you need a schema transformation to parse date strings from APIs or user input.
Details
Decoding creates a Date from the string like new Date(s). Encoding converts the Date to an ISO string like date.toISOString(), returning "Invalid Date" for invalid dates.
See
Signature
declare const dateFromString: Transformation<globalThis.Date, string>;numberFromString
Decodes a string into a number and encodes a number back to a string.
When to use
Use when you need a schema transformation to parse numeric strings from APIs, form data, or URL parameters.
Details
Decoding coerces the string to a number like Number(s). Encoding coerces the number to a string like String(n). This does not validate that the result is finite; combine with Schema.Finite or Schema.Int for stricter checks.
See
Signature
declare const numberFromString: Transformation<number, string, never, never>;Decoding
fromFormData
Decodes a FormData instance into a nested record using bracket-path keys and encodes object-like values back into FormData.
When to use
Use when you need a schema transformation for form or multipart payloads whose keys, such as user[name] or items[0], should become nested data.
Details
Decode preserves string and Blob leaves. Encode flattens nested objects and arrays into bracket-path entries and returns an empty FormData for non-object inputs.
See
Signature
declare const fromFormData: Transformation<unknown, FormData, never, never>;fromJsonString
Decodes a JSON string with JSON.parse and encodes a value with JSON.stringify.
When to use
Use when you need a schema transformation to decode JSON stored or transmitted as a string, usually before composing with another schema that validates the parsed structure.
Details
The reviver option is passed to JSON.parse during decoding. The replacer and space options are passed to JSON.stringify during encoding. Decode fails with InvalidValue for invalid JSON, and encode can fail with InvalidValue when JSON.stringify cannot serialize the value.
See
Signature
declare function fromJsonString(options?: {
readonly replacer?: JsonReplacer;
readonly reviver?: (this: any, key: string, value: any) => any;
readonly space?: string | number;
}): Transformation<unknown, string>;fromURLSearchParams
Decodes URLSearchParams into a nested record using bracket-path keys and encodes object-like values back into URLSearchParams.
When to use
Use when you need a schema transformation for query strings whose keys, such as filter[name] or items[0], should become nested data.
Details
Decode produces string leaves. Encode flattens nested objects and arrays into bracket-path entries and returns empty URLSearchParams for non-object inputs.
See
Signature
declare const fromURLSearchParams: Transformation<unknown, URLSearchParams, never, never>;Encoding
stringFromBase64String
Decodes a Base64-encoded string into a UTF-8 string and encodes a UTF-8 string back to a Base64 string.
When to use
Use when you need a schema transformation for text data transmitted as Base64 strings.
Details
Decoding parses the Base64 string into a UTF-8 string. Encoding writes the string as a Base64 string.
See
uint8ArrayFromBase64StringSchema.StringFromBase64- a ready-made schema wrapping this transformation.
Signature
declare const stringFromBase64String: Transformation<string, string>;stringFromBase64UrlString
Decodes a base64 (URL) encoded string into a UTF-8 string and encodes it back.
When to use
Use when you need a schema transformation for text data transmitted as Base64 URL-safe strings.
Details
Decoding parses the Base64 URL string into a UTF-8 string. Encoding writes the string as a Base64 URL string.
See
stringFromBase64StringSchema.StringFromBase64Url- a ready-made schema wrapping this transformation.
Signature
declare const stringFromBase64UrlString: Transformation<string, string>;stringFromHexString
Decodes a hex encoded string into a UTF-8 string and encodes it back.
When to use
Use when you need a schema transformation for text data transmitted as hexadecimal strings.
Details
Decoding parses the hex string into a UTF-8 string. Encoding writes the string as a hex string.
See
stringFromBase64StringSchema.StringFromHex- a ready-made schema wrapping this transformation.
Signature
declare const stringFromHexString: Transformation<string, string>;stringFromUriComponent
Decodes a URI component encoded string into a UTF-8 string and encodes a UTF-8 string into a URI component encoded string.
When to use
Use when you need a schema transformation to store structured data in URL query parameters or fragments, such as composing with Schema.parseJson to round-trip JSON through a URL.
Details
Decoding calls decodeURIComponent and fails if the input contains malformed percent-encoding sequences. Encoding calls encodeURIComponent.
See
stringFromBase64StringSchema.StringFromUriComponent- a ready-made schema wrapping this transformation.
Signature
declare const stringFromUriComponent: Transformation<string, string>;uint8ArrayFromBase64String
Decodes a Base64-encoded string into a Uint8Array and encodes a Uint8Array back to a Base64 string.
When to use
Use when you need a schema transformation for binary data transmitted as Base64 strings (e.g. file uploads, API payloads).
Details
Decoding parses the Base64 string into bytes. Encoding writes the byte array as a Base64 string.
See
fromJsonStringSchema.Uint8ArrayFromBase64- a ready-made schema wrapping this transformation.
Signature
declare const uint8ArrayFromBase64String: Transformation<Uint8Array<ArrayBufferLike>, string>;Guards
isTransformation
Returns true if u is a Transformation instance.
When to use
Use to check whether a value is already a schema transformation before wrapping it.
Details
- Pure predicate, no side effects. - Acts as a TypeScript type guard.
See
Signature
declare function isTransformation(u: unknown): u is Transformation<any, any, unknown, unknown>;Models
Middleware
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.
See
Transformation— value-level bidirectional transformation
Signature
declare class Middleware<in out T, in out E, RDE, RDT, RET, REE> {
constructor<in out T, in out E, RDE, RDT, RET, REE>(decode: (effect: Effect<Option<E>, Issue, RDE>, options: ParseOptions) => Effect<Option<T>, Issue, RDT>, encode: (effect: Effect<Option<T>, Issue, RET>, options: ParseOptions) => Effect<Option<E>, Issue, REE>);
readonly _tag: "Middleware";
readonly decode: (effect: Effect<Option<E>, Issue, RDE>, options: ParseOptions) => Effect<Option<T>, Issue, RDT>;
readonly encode: (effect: Effect<Option<T>, Issue, RET>, options: ParseOptions) => Effect<Option<E>, Issue, REE>;
flip(): Middleware<E, T, RET, REE, RDE, RDT>;
}Transformation
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.
See
make— construct from{ decode, encode }getterstransform— construct from pure functionstransformOrFail— construct from effectful functionsMiddleware— effect-pipeline-level alternative
Signature
declare class Transformation<in out T, in out E, RD = never, RE = never> {
constructor<in out T, in out E, RD = never, RE = never>(decode: Getter<T, E, RD>, encode: Getter<E, T, RE>);
readonly _tag: "Transformation";
readonly "~effect/SchemaTransformation/Transformation": "~effect/SchemaTransformation/Transformation";
readonly decode: Getter<T, E, RD>;
readonly encode: Getter<E, T, RE>;
compose<T2, RD2, RE2>(other: Transformation<T2, T, RD2, RE2>): Transformation<T2, E, RD | RD2, RE | RE2>;
flip(): Transformation<E, T, RE, RD>;
}Transforming
bigDecimalFromString
Decodes a string into a BigDecimal and encodes a BigDecimal back to its string representation.
When to use
Use when you need a schema transformation to parse decimal number strings from APIs or user input.
Details
Decoding calls BigDecimal.fromString(s) and fails with InvalidValue if the string is not a valid BigDecimal representation. Encoding returns BigDecimal.format(bd).
Signature
declare const bigDecimalFromString: Transformation<BigDecimal.BigDecimal, string>;capitalize
Transforms strings by capitalizing the first character on decode. Encode is passthrough.
When to use
Use when you need a schema transformation to normalize display names or titles.
Details
Decoding uppercases the first character and leaves the rest unchanged. Encoding is passthrough.
See
Signature
declare function capitalize(): Transformation<string, string>;dateTimeUtcFromString
Decodes a date-time string into a DateTime.Utc and encodes it back to an ISO string.
When to use
Use when you need a schema transformation to decode date-time strings to a normalized DateTime.Utc and encode back as a UTC ISO string.
Details
Decode accepts strings supported by DateTime.make, converts the result to UTC, and fails with InvalidValue when parsing fails. Encode uses DateTime.formatIso.
See
dateFromStringfor decoding into JavaScriptDatedateTimeZonedFromStringfor ISO strings that should preserve zoned date-time information
Signature
declare const dateTimeUtcFromString: Transformation<DateTime.Utc, string>;dateTimeZonedFromString
Decodes a zoned date-time string into a DateTime.Zoned and encodes it back to an ISO zoned string.
When to use
Use when you need a schema transformation for ISO zoned date-time strings that decode to DateTime.Zoned and encode with DateTime.formatIsoZoned.
Details
Decode uses DateTime.makeZonedFromString and fails with InvalidValue when the input is not a valid zoned date-time. Encode uses DateTime.formatIsoZoned.
See
dateTimeUtcFromStringfor date-time strings that should decode toDateTime.Utcand encode as UTC ISO strings
Signature
declare const dateTimeZonedFromString: Transformation<DateTime.Zoned, string>;durationFromMillis
Decodes a number of milliseconds into a Duration and encodes a Duration back to milliseconds.
When to use
Use when you need a schema transformation to decode timeouts, delays, elapsed intervals, or other duration values stored as millisecond counts.
Details
Decode creates a duration from the number, and encode returns the duration length in milliseconds.
See
Signature
declare const durationFromMillis: Transformation<Duration.Duration, number>;durationFromNanos
Decodes a bigint (nanoseconds) into a Duration and encodes a Duration back to bigint nanoseconds.
When to use
Use when you need a schema transformation for nanosecond-precision timestamps or intervals.
Details
Decoding always succeeds and creates a Duration from nanoseconds. Encoding fails with InvalidValue if the Duration cannot be represented as a bigint, such as Duration.infinity.
See
Signature
declare const durationFromNanos: Transformation<Duration.Duration, bigint>;durationFromString
Decodes a string into a Duration and encodes a Duration back to a parseable string.
When to use
Use when you need a schema transformation to parse human-readable duration strings from APIs, config, or user input.
Details
Decoding accepts any string that Duration.fromInput can parse, including "Infinity" and "-Infinity". Encoding returns String(duration), producing strings such as "2000 millis" or "10 nanos" that round-trip through the parser.
See
Signature
declare const durationFromString: Transformation<Duration.Duration, string>;optionFromNullishOr
Decodes T | null | undefined into Option<T> and encodes Option<T> back to T | null or T | undefined depending on the provided options.onNoneEncoding (defaults to undefined).
When to use
Use when you need a schema transformation to convert nullish API fields to Option when both null and undefined represent absence.
Details
Decoding maps null and undefined to Option.none() and all other values to Option.some(value). Encoding maps Option.none() to null or undefined according to options.onNoneEncoding, and maps Option.some(value) to value. The transformation is pure and synchronous.
See
Signature
declare function optionFromNullishOr<T>(options?: {
onNoneEncoding: null | undefined;
}): Transformation<Option<T>, T | null | undefined>;optionFromNullOr
Decodes T | null into Option<T> and encodes Option<T> back to T | null.
When to use
Use when you need a schema transformation to convert nullable API fields to Option.
Details
Decoding maps null to Option.none() and non-null values to Option.some(value). Encoding maps Option.none() to null and Option.some(value) to value. The transformation is pure and synchronous.
See
Signature
declare function optionFromNullOr<T>(): Transformation<Option<T>, T | null>;optionFromOptional
Decodes optional values into Option<T> and encodes Option.none() back to an omitted optional value.
When to use
Use when you need a schema transformation to convert optional (possibly undefined) values to Option.
Details
Decoding maps an absent or undefined value to Some(None) and a present value to Some(Some(v)). Encoding maps Some(None) to None to omit the value, and maps Some(Some(v)) to Some(v). This uses transformOptional under the hood and filters out undefined on decode.
See
Signature
declare function optionFromOptional<T>(): Transformation<Option<T>, T | undefined>;optionFromOptionalKey
Decodes an optional struct key into Option<T> and encodes Option<T> back to an optional key.
When to use
Use when you need a schema transformation to convert optional struct keys (declared with Schema.optionalKey) to Option values.
Details
Decoding maps an absent key (None) to Some(None) and a present key (Some(v)) to Some(Some(v)). Encoding maps Some(None) to None to omit the key, and maps Some(Some(v)) to Some(v). This uses transformOptional under the hood.
See
Signature
declare function optionFromOptionalKey<T>(): Transformation<Option<T>, T>;optionFromUndefinedOr
Decodes T | undefined into Option<T> and encodes Option.none() back to undefined.
When to use
Use when you need a schema transformation to convert API fields that use undefined for absence to Option.
Details
Decoding maps undefined to Option.none() and non-undefined values to Option.some(value). Encoding maps Option.none() to undefined and Option.some(value) to value. The transformation is pure and synchronous.
See
Signature
declare function optionFromUndefinedOr<T>(): Transformation<Option<T>, T | undefined>;snakeToCamel
Transforms strings by converting snake_case to camelCase on decode and camelCase to snake_case on encode.
When to use
Use when you need a schema transformation to convert API field names between snake_case and camelCase conventions.
Details
Decoding converts values such as "my_field_name" to "myFieldName". Encoding converts values such as "myFieldName" back to "my_field_name". The transformation is round-trippable for standard snake_case and camelCase.
See
Signature
declare function snakeToCamel(): Transformation<string, string>;splitKeyValue
Transforms a string into a record of key-value pairs and encodes a record of key-value pairs into a string.
When to use
Use when you need a schema transformation to parse query-string-like or config-file-like strings into records.
Details
Decoding splits the string by separator (default ",") into pairs, then splits each pair by keyValueSeparator (default "="). Encoding joins the record back into a string using the same separators. The transformation is round-trippable when keys and values do not contain the separators.
See
Signature
declare function splitKeyValue(options?: {
readonly keyValueSeparator?: string;
readonly separator?: string;
}): Transformation<Record<string, string>, string>;timeZoneFromString
Decodes a string into a DateTime.TimeZone and encodes a time zone back to its string representation.
When to use
Use when you need a schema transformation to accept either an IANA time-zone identifier or an offset string and produce a general DateTime.TimeZone.
Details
Accepted decode inputs include valid IANA identifiers and offset strings such as "+03:00". Decode fails with InvalidValue when the string cannot be parsed as a time zone.
See
timeZoneNamedFromStringfor IANA named-zone strings onlytimeZoneOffsetFromNumberfor fixed-offset zones encoded as numbers
Signature
declare const timeZoneFromString: Transformation<DateTime.TimeZone, string>;timeZoneNamedFromString
Decodes an IANA time-zone identifier string into a DateTime.TimeZone.Named and encodes a named time zone back to its id.
When to use
Use when you need a schema transformation to accept only IANA time-zone identifier strings and produce DateTime.TimeZone.Named values.
Details
Decode fails with InvalidValue when the string is not a valid IANA time-zone identifier.
See
timeZoneFromStringfor time-zone strings that may be either IANA identifiers or offset strings
Signature
declare const timeZoneNamedFromString: Transformation<DateTime.TimeZone.Named, string>;timeZoneOffsetFromNumber
Decodes a numeric time-zone offset in milliseconds into a DateTime.TimeZone.Offset and encodes it back to the offset number.
When to use
Use when you need a schema transformation to represent fixed-offset time zones with numeric millisecond offsets.
Details
Decode uses DateTime.zoneMakeOffset; encode returns the offset's offset field.
See
timeZoneFromStringfor IANA or offset string encodingstimeZoneNamedFromStringfor IANA named-zone strings
Signature
declare const timeZoneOffsetFromNumber: Transformation<DateTime.TimeZone.Offset, number>;toLowerCase
Transforms strings by lowercasing on decode. Encode is passthrough.
When to use
Use when you need a schema transformation to normalize strings to lowercase (e.g. email addresses).
Details
Decoding applies String.prototype.toLowerCase(). Encoding is passthrough. This is not round-trippable if the original had uppercase characters.
See
Signature
declare function toLowerCase(): Transformation<string, string>;toUpperCase
Transforms strings by uppercasing on decode. Encode is passthrough.
When to use
Use when you need a schema transformation to normalize strings to uppercase (e.g. country codes).
Details
Decoding applies String.prototype.toUpperCase(). Encoding is passthrough. This is not round-trippable if the original had lowercase characters.
See
Signature
declare function toUpperCase(): Transformation<string, string>;Creates a Transformation from pure (sync, infallible) decode and encode functions.
When to use
Use when you need an infallible schema transformation that does not require Effect services.
Details
- Each function receives the input and returns the output directly. - Skips None inputs (missing keys) — functions are only called on present values. - Does not allocate Effects internally; uses optimized sync path.
See
transformOrFail— for fallible or effectful transformationstransformOptional— for transformations that handle missing keyspassthrough— when no conversion is needed
Signature
declare function transform<T, E>(options: {
readonly decode: (input: E) => T;
readonly encode: (input: T) => E;
}): Transformation<T, E>;transformOptional
Creates a Transformation where decode and encode operate on Option values, giving full control over missing-key handling.
When to use
Use when you need a schema transformation to produce or consume Option.None for absent keys. - You are working with optional struct fields.
Details
- Each function receives Option<input> and returns Option<output>. - Option.None input means the key is absent; returning Option.None omits the key from the output. - Pure and synchronous.
See
transform— when you don't need Option-level controloptionFromOptionalKey— built-in for the common optional-key-to-Option patternoptionFromOptional— built-in for optional (undefined) to Option
Signature
declare function transformOptional<T, E>(options: {
readonly decode: (input: Option<E>) => Option<T>;
readonly encode: (input: Option<T>) => Option<E>;
}): Transformation<T, E>;transformOrFail
Creates a Transformation from effectful decode and encode functions that can fail with Issue.
When to use
Use when you need a schema transformation that may fail or require Effect services.
Details
- Each function receives the input value and ParseOptions. - Must return an Effect that succeeds with the output or fails with Issue. - Skips None inputs (missing keys) — functions are only called on present values.
See
transform— for infallible, pure transformationstransformOptional— for transformations that handle missing keysmake— for transformations from existing Getters
Signature
declare function transformOrFail<T, E, RD = never, RE = never>(options: {
readonly decode: (e: E, options: ParseOptions) => Effect<T, Issue, RD>;
readonly encode: (t: T, options: ParseOptions) => Effect<E, Issue, RE>;
}): Transformation<T, E, RD, RE>;Transforms strings by trimming whitespace on decode. Encode is passthrough (no change).
When to use
Use when you need a schema transformation to normalize user input by stripping leading/trailing whitespace.
Details
Decoding applies String.prototype.trim(). Encoding is passthrough and returns the string unchanged. This is not round-trippable if the original had whitespace.
See
Signature
declare function trim(): Transformation<string, string>;uncapitalize
Transforms strings by lowercasing the first character on decode. Encode is passthrough.
When to use
Use when you need a schema transformation to normalize identifiers or field names.
Details
Decoding lowercases the first character and leaves the rest unchanged. Encoding is passthrough.
See
Signature
declare function uncapitalize(): Transformation<string, string>;urlFromString
Decodes a string into a URL and encodes a URL back to its href string.
When to use
Use when you need a schema transformation to parse URL strings from user input or API responses.
Details
Decoding checks URL.canParse(s) and fails with InvalidValue if the string is not a valid URL. Encoding returns url.href.
See
Signature
declare const urlFromString: Transformation<URL, string>;
Constructs a
Transformationfrom an object withdecodeandencodeGetters. If the input is already aTransformation, returns it as-is.When to use
Use when you already have schema getter instances and want to pair them into a schema transformation. - You want idempotent wrapping (won't double-wrap).
Details
- Returns the input unchanged if it is already a
Transformation.See
transform— simpler constructor from pure functionstransformOrFail— constructor from effectful functionsTransformation