Hyperlinkv0.8.0-beta.28

Schema

Schema.declareConstructorfunctioneffect/Schema.ts:311
declareConstructor<T, E, TypeParameters, Iso>

Creates a schema for a parametric type (a generic container such as Array<A>, Option<A>, etc.) by accepting a list of type-parameter schemas and a decoder factory.

When to use

Use when you are defining a schema for a generic container whose validation depends on one or more type-parameter schemas.

Details

The outer call declareConstructor<T, E, Iso>() fixes the decoded type T, the encoded type E, and the optional iso type. The inner call receives:

  • typeParameters — the concrete schemas for each type variable
  • run — a factory that, given resolved codecs for each type parameter, returns a parsing function (u, ast, options) => Effect<T, Issue>
  • annotations — optional metadata
constructorsdeclare
Source effect/Schema.ts:31191 lines
export interface declareConstructor<T, E, TypeParameters extends ReadonlyArray<Constraint>, Iso = T> extends
  Bottom<
    T,
    E,
    TypeParameters[number]["DecodingServices"],
    TypeParameters[number]["EncodingServices"],
    SchemaAST.Declaration,
    declareConstructor<T, E, TypeParameters, Iso>,
    T,
    Iso,
    TypeParameters
  >
{}

/**
 * Creates a schema for a **parametric** type (a generic container such as
 * `Array<A>`, `Option<A>`, etc.) by accepting a list of type-parameter schemas
 * and a decoder factory.
 *
 * **When to use**
 *
 * Use when you are defining a schema for a generic container whose validation
 * depends on one or more type-parameter schemas.
 *
 * **Details**
 *
 * The outer call `declareConstructor<T, E, Iso>()` fixes the decoded type `T`,
 * the encoded type `E`, and the optional iso type. The inner call receives:
 * - `typeParameters` — the concrete schemas for each type variable
 * - `run` — a factory that, given resolved codecs for each type parameter,
 *   returns a parsing function `(u, ast, options) => Effect<T, Issue>`
 * - `annotations` — optional metadata
 *
 * @see {@link declare} for creating schemas for non-parametric types.
 *
 * **Example** (Schema for a parametric `Box<A>` type)
 *
 * ```ts
 * import { Effect, Option, Schema, SchemaIssue as Issue, SchemaParser } from "effect"
 *
 * interface Box<A> {
 *   readonly value: A
 * }
 *
 * const isBox = (u: unknown): u is Box<unknown> =>
 *   typeof u === "object" && u !== null && "value" in u
 *
 * const Box = <A extends Schema.Constraint>(item: A) =>
 *   Schema.declareConstructor<Box<A["Type"]>, Box<A["Encoded"]>>()(
 *     [item],
 *     ([itemCodec]) =>
 *       (u, ast, options) => {
 *         if (!isBox(u)) {
 *           return Effect.fail(new SchemaIssue.InvalidType(ast, Option.some(u)))
 *         }
 *         return Effect.map(
 *           SchemaParser.decodeUnknownEffect(itemCodec)(u.value, options),
 *           (value) => ({ value })
 *         )
 *       }
 *   )
 *
 * const schema = Box(Schema.Number)
 * ```
 *
 * @category constructors
 * @since 4.0.0
 */
export function declareConstructor<T, E = T, Iso = T>() {
  return <const TypeParameters extends ReadonlyArray<Constraint>>(
    typeParameters: TypeParameters,
    run: (
      typeParameters: {
        readonly [K in keyof TypeParameters]: Codec<TypeParameters[K]["Type"], TypeParameters[K]["Encoded"]>
      }
    ) => (
      u: unknown,
      self: SchemaAST.Declaration,
      options: SchemaAST.ParseOptions
    ) => Effect.Effect<T, SchemaIssue.Issue>,
    annotations?: Annotations.Declaration<T, TypeParameters>
  ): declareConstructor<T, E, TypeParameters, Iso> => {
    return make(
      new SchemaAST.Declaration(
        typeParameters.map(SchemaAST.getAST),
        (typeParameters) => run(typeParameters.map((ast) => make(ast)) as any),
        annotations
      )
    )
  }
}
Referenced by 15 symbols