Hyperlinkv0.8.0-beta.28

Schema

Schema.decodeTofunctioneffect/Schema.ts:5378
decodeTo<To, From, RD, RE>

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
transforming
Source effect/Schema.ts:5378108 lines
export interface decodeTo<To extends Constraint, From extends Constraint, RD = never, RE = never> extends
  BottomLazy<
    To["ast"],
    decodeTo<To, From, RD, RE>,
    To["~type.parameters"],
    To["~type.mutability"],
    To["~type.optionality"],
    To["~type.constructor.default"],
    From["~encoded.mutability"],
    From["~encoded.optionality"]
  >
{
  readonly "Type": To["Type"]
  readonly "Encoded": From["Encoded"]
  readonly "DecodingServices": To["DecodingServices"] | From["DecodingServices"] | RD
  readonly "EncodingServices": To["EncodingServices"] | From["EncodingServices"] | RE
  readonly "~type.make.in": To["~type.make.in"]
  readonly "~type.make": To["~type.make"]
  readonly "Iso": To["Iso"]
  readonly from: From
  readonly to: To
}

/**
 * Type-level representation returned by {@link decodeTo} without a custom transformation.
 *
 * @category transforming
 * @since 3.10.0
 */
export interface compose<To extends Constraint, From extends Constraint> extends decodeTo<To, From> {}

/**
 * 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)
 *
 * ```ts
 * 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
 * ```
 *
 * @category transforming
 * @since 4.0.0
 */
export function decodeTo<To extends Constraint>(to: To): <From extends Constraint>(from: From) => compose<To, From>
export function decodeTo<To extends Constraint, From extends Constraint, RD = never, RE = never>(
  to: To,
  transformation: {
    readonly decode: SchemaGetter.Getter<NoInfer<To["Encoded"]>, NoInfer<From["Type"]>, RD>
    readonly encode: SchemaGetter.Getter<NoInfer<From["Type"]>, NoInfer<To["Encoded"]>, RE>
  }
): (from: From) => decodeTo<To, From, RD, RE>
export function decodeTo<To extends Constraint, From extends Constraint, RD = never, RE = never>(
  to: To,
  transformation?: {
    readonly decode: SchemaGetter.Getter<To["Encoded"], From["Type"], RD>
    readonly encode: SchemaGetter.Getter<From["Type"], To["Encoded"], RE>
  } | undefined
) {
  return (from: From) => {
    return make(
      SchemaAST.decodeTo(
        from.ast,
        to.ast,
        transformation ? SchemaTransformation.make(transformation) : SchemaTransformation.passthrough()
      ),
      {
        from,
        to
      }
    )
  }
}
Referenced by 54 symbols