/** * Describes data shapes and how unknown input becomes trusted values. * * A schema can validate input, decode it into an application type, and encode * that value back to another representation. This module contains the main * schema, codec, decoder, and encoder APIs, together with schemas for common * JavaScript values and Effect data types. It also supports refinements, * transformations, defaults, classes, JSON Schema generation, test data * generation, formatting, equivalence, optics, and differs derived from schema * definitions. * * @stability stable * @since 4.0.0 */ import * as Arr from "./Array.ts" import * as BigDecimal_ from "./BigDecimal.ts" import type * as Brand from "./Brand.ts" import * as ByteSize_ from "./ByteSize.ts" import * as Cause_ from "./Cause.ts" import * as Chunk_ from "./Chunk.ts" import * as Data from "./Data.ts" import * as DateTime from "./DateTime.ts" import type { Differ } from "./Differ.ts" import * as Duration_ from "./Duration.ts" import * as Effect from "./Effect.ts" import * as Base64 from "./encoding/Base64.ts" import * as Equal from "./Equal.ts" import type * as Equivalence from "./Equivalence.ts" import * as Exit_ from "./Exit.ts" import type { Formatter } from "./Formatter.ts" import { format, formatPropertyKey } from "./Formatter.ts" import { identity } from "./Function.ts" import type * as Graph_ from "./Graph.ts" import * as HashMap_ from "./HashMap.ts" import * as HashSet_ from "./HashSet.ts" import * as Cookies_ from "./http/Cookies.ts" import * as Headers_ from "./http/Headers.ts" import * as UrlParams_internal from "./http/internal/urlParams.ts" import * as UrlParams_ from "./http/UrlParams.ts" import { NodeInspectSymbol } from "./Inspectable.ts" import * as core from "./internal/core.ts" import { effectIsExit } from "./internal/effect.ts" import * as InternalGraph from "./internal/graph.ts" import * as InternalRecord from "./internal/record.ts" import * as InternalAnnotations from "./internal/schema/annotations.ts" import * as InternalMake from "./internal/schema/make.ts" import * as InternalStandardSchema from "./internal/schema/standardSchema.ts" import * as InternalToCodec from "./internal/schema/toCodec.ts" import * as InternalToDifferJsonPatch from "./internal/schema/toDifferJsonPatch.ts" import * as InternalToEncoderXml from "./internal/schema/toEncoderXml.ts" import * as InternalEquivalence from "./internal/schema/toEquivalence.ts" import * as InternalToFormatter from "./internal/schema/toFormatter.ts" import * as InternalToIso from "./internal/schema/toIso.ts" import * as InternalToJsonSchemaDocument from "./internal/schema/toJsonSchemaDocument.ts" import * as InternalToRepresentation from "./internal/schema/toRepresentation.ts" import { isSchemaError as isSchemaErrorInternal, SchemaErrorTypeId } from "./internal/schemaError.ts" import { getStackTraceLimit, setStackTraceLimit } from "./internal/stackTraceLimit.ts" import type * as JsonPatch from "./JsonPatch.ts" import type * as JsonSchema from "./JsonSchema.ts" import * as Dns_ from "./net/Dns.ts" import * as Host_ from "./net/Host.ts" import * as IpInterface_ from "./net/IpInterface.ts" import * as IpNetwork_ from "./net/IpNetwork.ts" import * as NetAddress_ from "./net/NetAddress.ts" import { remainder } from "./Number.ts" import type * as Optic_ from "./Optic.ts" import * as Option_ from "./Option.ts" import * as Order from "./Order.ts" import * as Pipeable from "./Pipeable.ts" import * as Predicate from "./Predicate.ts" import * as Record_ from "./Record.ts" import * as Redacted_ from "./Redacted.ts" import * as RegExp_ from "./RegExp.ts" import * as Result_ from "./Result.ts" import * as SchemaAST from "./SchemaAST.ts" import * as SchemaGetter from "./SchemaGetter.ts" import * as SchemaIssue from "./SchemaIssue.ts" import * as SchemaParser from "./SchemaParser.ts" import type * as SchemaRepresentation from "./SchemaRepresentation.ts" import * as SchemaTransformation from "./SchemaTransformation.ts" import * as SemVer_ from "./SemVer.ts" import * as SemVerRange_ from "./SemVerRange.ts" import type { StandardJSONSchemaV1, StandardSchemaV1 } from "./StandardSchema.ts" import type { Assign, Lambda, Mutable, Simplify } from "./Struct.ts" import * as Struct_ from "./Struct.ts" import type { IsUnion, RequiredKeys } from "./Types.ts" import type { Unify } from "./Unify.ts" const TypeId = InternalMake.TypeId /** * Whether a schema field is required or optional within a struct. * * @see {@link optionalKey} — mark a struct field as optional * @see {@link optional} — mark a struct field as optional with `| undefined` * * @stability stable * @category models * @since 4.0.0 */ export type Optionality = "required" | "optional" /** * Whether a schema field is readonly or mutable within a struct. * * @see {@link mutableKey} — mark a struct field as mutable * * @stability stable * @category models * @since 4.0.0 */ export type Mutability = "readonly" | "mutable" /** * Whether a schema field has a constructor default value. * * @see {@link withConstructorDefault} — add a default to a schema field * @see {@link tag} — creates a literal field with a constructor default * * @stability stable * @category models * @since 4.0.0 */ export type ConstructorDefault = "no-default" | "with-default" /** * Options for `makeEffect`, `make`, and Class constructors. * * **When to use** * * Use when passing `disableChecks: true` to skip filters and checks while still * parsing types and structure. Pass `parseOptions` to control parsing behavior. * * @see {@link BottomWithoutNew.makeEffect} * @see {@link BottomWithoutNew.make} * * @stability stable * @category options * @since 3.13.4 */ export interface MakeOptions { /** * The parse options to use for the schema. */ readonly parseOptions?: SchemaAST.ParseOptions | undefined /** * Whether to skip filters and checks. Types and structure are still parsed, * and constructor defaults still apply. */ readonly disableChecks?: boolean | undefined /** @internal */ readonly "~payload"?: { readonly token: unknown readonly value: unknown } } /** * The fully-parameterized schema interface without a construct signature. * Exposes all 14 type parameters controlling type inference, mutability, * optionality, services, and transformation behavior. * * **When to use** * * Use as the base for schema interfaces that provide a specialized construct * signature. * * @stability stable * @category models * @since 4.0.0 */ export interface BottomWithoutNew< out T, out E, out RD, out RE, out Ast extends SchemaAST.AST, out Rebuild extends Top, out TypeMakeIn = T, out Iso = T, in out TypeParameters extends ReadonlyArray = readonly [], out TypeMake = TypeMakeIn, out TypeMutability extends Mutability = "readonly", out TypeOptionality extends Optionality = "required", out TypeConstructorDefault extends ConstructorDefault = "no-default", out EncodedMutability extends Mutability = "readonly", out EncodedOptionality extends Optionality = "required" > extends Pipeable.Pipeable { readonly [TypeId]: typeof TypeId readonly "ast": Ast readonly "Rebuild": Rebuild readonly "~type.parameters": TypeParameters readonly "Type": T readonly "Encoded": E readonly "DecodingServices": RD readonly "EncodingServices": RE readonly "~type.make.in": TypeMakeIn readonly "~type.make": TypeMake readonly "~type.constructor.default": TypeConstructorDefault readonly "Iso": Iso readonly "~type.mutability": TypeMutability readonly "~type.optionality": TypeOptionality readonly "~encoded.mutability": EncodedMutability readonly "~encoded.optionality": EncodedOptionality annotate(annotations: Annotations.Bottom): this["Rebuild"] annotateKey(annotations: Annotations.Key): this["Rebuild"] check(...checks: readonly [SchemaAST.Check, ...Array>]): this["Rebuild"] rebuild(ast: this["ast"]): this["Rebuild"] /** * Constructs a value from the make input representation synchronously. * * **When to use** * * Use when constructor input is trusted or when validation failure * should abort with a thrown `Error`. * * **Details** * * Applies constructor defaults and type-side validation according to * `MakeOptions`. * * **Gotchas** * * Throws an `Error` with the schema issue in its `cause` when validation * fails. Schema validation failures use the generic message * `"Schema validation failed"`; format the `cause` explicitly with * `SchemaIssue.makeFormatterDefault()` when human-readable details are needed. * Causes that contain defects, interruptions, or other non-schema reasons * throw with the underlying `Cause` attached instead. * * @see {@link BottomWithoutNew.makeOption} — construct synchronously and discard validation details * @see {@link BottomWithoutNew.makeEffect} — construct through `Effect` when validation failure should stay in the error channel */ make(input: this["~type.make.in"], options?: MakeOptions): this["Type"] /** * Constructs a value from the make input representation, returning `Option.none` * when validation fails. * * **When to use** * * Use when you only need to know whether construction succeeds * and do not need validation details. * * **Details** * * Applies constructor defaults and type-side validation according to * `MakeOptions`. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `None`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * @see {@link BottomWithoutNew.make} — construct synchronously when validation failure should throw * @see {@link BottomWithoutNew.makeEffect} — construct through `Effect` when validation details should stay in the error channel */ makeOption(input: this["~type.make.in"], options?: MakeOptions): Option_.Option /** * Constructs a value from the make input representation, returning validation * failures in the `Effect` error channel. * * **When to use** * * Use when construction must compose with other `Effect` operations or when * the result supplies a nested constructor default. Otherwise, use * {@link BottomWithoutNew.make} when invalid construction should throw. * * **Details** * * `SchemaParser` uses `SchemaIssue.Issue` as its canonical structured failure, * and this method exposes the same representation directly. Keeping the issue * unwrapped lets an enclosing schema attach its own path when the effect is * used with {@link withConstructorDefault}. It also avoids allocating a * `SchemaError` and keeps its formatting path out of the resulting bundle. * * **Gotchas** * * Unlike the decoding helpers in `Schema`, validation failures are not wrapped * in `SchemaError`. Map the issue to `SchemaError` or to a domain-specific error * when a wrapped error is needed at the application boundary. * * @see {@link BottomWithoutNew.make} — construct synchronously when validation failure should throw * @see {@link BottomWithoutNew.makeOption} — construct synchronously and discard validation details */ makeEffect(input: this["~type.make.in"], options?: MakeOptions): Effect.Effect } /** * Fully-parameterized base interface for schemas that can be extended directly * by TypeScript classes. * * **When to use** * * Use as the base for concrete schema interfaces whose runtime values support * `class ... extends schema`. * * **Details** * * Extends {@link BottomWithoutNew} with a construct signature that accepts `never`. The * signature enables class extension without making ordinary schemas directly * constructible. * * @see {@link BottomWithoutNew} for the schema protocol without a construct signature * * @stability stable * @category utility types * @since 4.0.0 */ export interface Bottom< out T, out E, out RD, out RE, out Ast extends SchemaAST.AST, out Rebuild extends Top, out TypeMakeIn = T, out Iso = T, in out TypeParameters extends ReadonlyArray = readonly [], out TypeMake = TypeMakeIn, out TypeMutability extends Mutability = "readonly", out TypeOptionality extends Optionality = "required", out TypeConstructorDefault extends ConstructorDefault = "no-default", out EncodedMutability extends Mutability = "readonly", out EncodedOptionality extends Optionality = "required" > extends BottomWithoutNew< T, E, RD, RE, Ast, Rebuild, TypeMakeIn, Iso, TypeParameters, TypeMake, TypeMutability, TypeOptionality, TypeConstructorDefault, EncodedMutability, EncodedOptionality > { new(_: never): {} } /** * Lazy `BottomWithoutNew` variant for schema implementations that * compute their public views on demand. * * **When to use** * * Use as the base for lazy schema interfaces that provide a specialized * construct signature. * * **Details** * * The laziness is purely type-level; runtime behavior is unchanged. * `BottomLazyWithoutNew` keeps the structural operations inherited from * `BottomWithoutNew`, but erases the expensive schema views to * `unknown`. Concrete schema interfaces can then redeclare the precise views * they expose. This keeps wide schemas such as `Struct` and `Union` cheaper when * generic code reads a single view, while preserving their exact public types. * * @see {@link BottomWithoutNew} for the fully parameterized schema interface when every * view must be supplied directly. * * @stability stable * @category utility types * @since 4.0.0 */ export interface BottomLazyWithoutNew< out Ast extends SchemaAST.AST, out Rebuild extends Top, in out TypeParameters extends ReadonlyArray = readonly [], out TypeMutability extends Mutability = "readonly", out TypeOptionality extends Optionality = "required", out TypeConstructorDefault extends ConstructorDefault = "no-default", out EncodedMutability extends Mutability = "readonly", out EncodedOptionality extends Optionality = "required" > extends BottomWithoutNew< unknown, unknown, unknown, unknown, Ast, Rebuild, unknown, unknown, TypeParameters, unknown, TypeMutability, TypeOptionality, TypeConstructorDefault, EncodedMutability, EncodedOptionality > {} /** * Lazy `Bottom` variant for schemas that can be extended directly by TypeScript * classes. * * **When to use** * * Use as the base for concrete lazy schema interfaces whose runtime values * support `class ... extends schema`. * * **Details** * * Extends {@link BottomLazyWithoutNew} with a construct signature that accepts `never`. * The signature enables class extension without making ordinary schemas * directly constructible. * * @see {@link BottomLazyWithoutNew} for the lazy schema protocol without a construct signature * * @stability stable * @category utility types * @since 4.0.0 */ export interface BottomLazy< out Ast extends SchemaAST.AST, out Rebuild extends Top, in out TypeParameters extends ReadonlyArray = readonly [], out TypeMutability extends Mutability = "readonly", out TypeOptionality extends Optionality = "required", out TypeConstructorDefault extends ConstructorDefault = "no-default", out EncodedMutability extends Mutability = "readonly", out EncodedOptionality extends Optionality = "required" > extends BottomLazyWithoutNew< Ast, Rebuild, TypeParameters, TypeMutability, TypeOptionality, TypeConstructorDefault, EncodedMutability, EncodedOptionality > { new(_: never): {} } /** * Type-level representation returned by {@link declareConstructor}. * * @stability stable * @category constructors * @since 4.0.0 */ export interface declareConstructor, Iso = T> extends Bottom< T, E, TypeParameters[number]["DecodingServices"], TypeParameters[number]["EncodingServices"], SchemaAST.Declaration, declareConstructor, T, Iso, TypeParameters > {} /** * Creates a schema for a **parametric** type (a generic container such as * `Array`, `Option`, 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()` 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` * - `annotations` — optional metadata * * @see {@link declare} for creating schemas for non-parametric types. * * **Example** (Schema for a parametric `Box` type) * * ```ts import.meta.vitest * import { Effect, Schema, SchemaIssue, SchemaParser } from "effect" * * interface Box { * readonly value: A * } * * const isBox = (u: unknown): u is Box => * typeof u === "object" && u !== null && "value" in u * * const Box = (item: A) => * Schema.declareConstructor, Box>()( * [item], * ([itemCodec]) => * (u, ast, options) => { * if (!isBox(u)) { * return Effect.fail(new SchemaIssue.InvalidType(ast, u, options)) * } * return Effect.map( * SchemaParser.decodeUnknownEffect(itemCodec)(u.value, options), * (value) => ({ value }) * ) * } * ) * * const schema = Box(Schema.Number) * Effect.runSync(Schema.decodeUnknownEffect(schema)({ value: 1 })) // => { value: 1 } * ``` * * @stability stable * @category constructors * @since 4.0.0 */ export function declareConstructor() { return >( typeParameters: TypeParameters, run: ( typeParameters: { readonly [K in keyof TypeParameters]: Codec } ) => ( u: unknown, self: SchemaAST.Declaration, options: SchemaAST.ParseOptions ) => Effect.Effect, annotations?: Annotations.Declaration ): declareConstructor => { return make( new SchemaAST.Declaration( typeParameters.map(SchemaAST.getAST), (typeParameters) => run(typeParameters.map((ast) => make(ast)) as any), annotations ) ) } } /** * Type-level representation returned by {@link declare}. * * @stability stable * @category constructors * @since 3.13.3 */ export interface declare extends declareConstructor { readonly "Rebuild": declare } /** * Creates a schema for a **non-parametric** opaque type using a type-guard * function. The schema accepts any unknown value and succeeds when `is` returns * `true`, failing with an `InvalidType` issue otherwise. * * **When to use** * * Use when you are defining a schema for an opaque type with no type parameters * and validation can be expressed as a type guard. * * **Example** (Defining a schema for a custom `UserId` branded type) * * ```ts import.meta.vitest * import { Schema } from "effect" * * type UserId = string & { readonly _tag: "UserId" } * * const isUserId = (u: unknown): u is UserId => * typeof u === "string" && u.startsWith("user_") * * const UserId = Schema.declare(isUserId, { * title: "UserId", * description: "A user identifier starting with 'user_'" * }) * Schema.decodeUnknownSync(UserId)("user_123") // => "user_123" * ``` * * @see {@link declareConstructor} for creating schemas for parametric types. * * @stability stable * @category constructors * @since 3.10.0 */ export function declare( is: (u: unknown) => u is T, annotations?: Annotations.Declaration | undefined ): declare { return declareConstructor()( [], () => (input, ast, options) => is(input) ? Effect.succeed(input) : Effect.fail(new SchemaIssue.InvalidType(ast, input, options)), annotations ) } /** * Returns a schema widened to the fully-parameterized {@link Bottom} interface, * making all 14 type parameters visible to TypeScript. * * **Details** * * Normally, concrete schema interfaces (e.g. `Schema`) hide most type * parameters. `revealBottom` is useful when writing generic utilities that need * to inspect or propagate the complete set of type parameters. * * **Example** (Inspecting all type parameters of a schema) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.String * * // Widen to Bottom to access all 14 type parameters * const bottom = Schema.revealBottom(schema) * * // `bottom` now exposes Type, Encoded, DecodingServices, EncodingServices, * // ast, Rebuild, ~type.make.in, Iso, ~type.parameters, etc. * type T = typeof bottom["Type"] // string * type E = typeof bottom["Encoded"] // string * ``` * * @stability stable * @category utility types * @since 4.0.0 */ export function revealBottom( bottom: S ): Bottom< S["Type"], S["Encoded"], S["DecodingServices"], S["EncodingServices"], S["ast"], S["Rebuild"], S["~type.make.in"], S["Iso"], S["~type.parameters"], S["~type.make"], S["~type.mutability"], S["~type.optionality"], S["~type.constructor.default"], S["~encoded.mutability"], S["~encoded.optionality"] > { return bottom } /** * Adds metadata annotations to a schema without changing its runtime behavior. * This is the pipeable (curried) counterpart of the `.annotate` method. * * **Details** * * Annotations provide extra context used by documentation generators, JSON * Schema converters, error formatters, and other tooling. Common keys include * `title`, `description`, `examples`, `message`, and `identifier`. * * **Example** (Adding a title and description) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const Age = Schema.Natural.pipe( * Schema.annotate({ * title: "Age", * description: "A non-negative integer representing age in years" * }) * ) * Schema.resolveAnnotations(Age)?.title // => "Age" * ``` * * @see {@link annotateEncoded} to annotate the encoded side instead. * * @stability stable * @category annotations * @since 4.0.0 */ export function annotate(annotations: Annotations.Bottom) { return (self: S) => self.annotate(annotations) } /** * Adds metadata annotations to the **encoded** side of a schema without * changing its runtime behavior. This is the encoded-side counterpart of * `annotate`, which targets the decoded (Type) side. * * **Details** * * Internally the schema is flipped so that `Encoded` becomes `Type`, * annotated, and then flipped back. * * **Example** (Adding a title to the encoded representation) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.NumberFromString.pipe( * Schema.annotateEncoded({ * title: "my title" * }) * ) * * Schema.toEncoded(schema).ast.annotations?.title // => "my title" * ``` * * @see {@link annotate} to annotate the type side instead. * * @stability stable * @category annotations * @since 4.0.0 */ export function annotateEncoded(annotations: Annotations.Bottom) { return (self: S): S["Rebuild"] => flip(flip(self).annotate(annotations)) } /** * Adds key-level annotations to a schema field. This is the pipeable * (curried) counterpart of the `.annotateKey` method. * * **Details** * * Key annotations apply to a field's position inside a `Struct` or `Tuple` * rather than to the field's value type. They can carry a * `messageMissingKey` to customise the error shown when the field is absent, * as well as standard documentation fields such as `title`, `description`, * and `examples`. * * **Example** (Customizing the missing-key message for a required field) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.Struct({ * username: Schema.String.pipe( * Schema.annotateKey({ * description: "The username used to log in", * messageMissingKey: "Username is required" * }) * ) * }) * schema.fields.username.ast.context?.annotations?.messageMissingKey // => "Username is required" * ``` * * @stability stable * @category annotations * @since 4.0.0 */ export function annotateKey(annotations: Annotations.Key) { return (self: S): S["Rebuild"] => { return self.rebuild(SchemaAST.annotateKey(self.ast, annotations)) } } /** * The existential "any schema" type — all type parameters are erased to `unknown`. * * **Details** * * Use `Top` as a constraint when writing generic utilities that must accept *any* * schema regardless of its `Type`, `Encoded`, or service requirements. It is the * widest possible schema type and therefore gives you the least static information. * * In user code prefer the narrower interfaces: * - {@link Schema}`` — when you only care about the decoded type * - {@link Codec}`` — when you need the encoded type and service requirements * - {@link ConstraintDecoder}`` — for decode-only APIs * - {@link ConstraintEncoder}`` — for encode-only APIs * * @stability stable * @category models * @since 4.0.0 */ export interface Top extends Bottom< unknown, unknown, unknown, unknown, SchemaAST.AST, Top, unknown, unknown, any, // this is because TypeParameters is invariant unknown, Mutability, Optionality, ConstructorDefault, Mutability, Optionality > {} /** * Lightweight structural constraint for APIs that accept schema values but only * read their data and type-level views. * * **When to use** * * Use when you need to constrain a generic value to be a schema, but the API * only reads properties such as `ast`, `Type`, `Encoded`, service * requirements, constructor input views, or modifier flags. * * **Details** * * `Constraint` keeps the schema type identifier and the property surface needed * by schema constructors, while avoiding the full `Bottom` protocol. Use * {@link Top} when an API calls schema methods such as `annotate`, `check`, * `rebuild`, `make`, or `makeEffect`. * * @see {@link Top} for the complete schema protocol. * * @stability stable * @category models * @since 4.0.0 */ export interface Constraint { readonly [TypeId]: typeof TypeId readonly "ast": SchemaAST.AST readonly "Type": unknown readonly "Encoded": unknown readonly "DecodingServices": unknown readonly "EncodingServices": unknown readonly "~type.parameters": any readonly "~type.make.in": unknown readonly "~type.make": unknown readonly "Iso": unknown readonly "~type.optionality": Optionality readonly "~type.mutability": Mutability readonly "~type.constructor.default": ConstructorDefault readonly "~encoded.optionality": Optionality readonly "~encoded.mutability": Mutability } /** * Lightweight structural constraint for APIs that need codec type views but do * not need the full schema protocol. * * **When to use** * * Use when you need to preserve decoded type, encoded type, and service * requirements for a schema value, but the API does not call schema methods * such as `annotate`, `check`, `rebuild`, `make`, or `makeEffect`. * * @see {@link Constraint} for the generic lightweight schema constraint. * @see {@link Codec} for the full schema protocol with codec type views. * * @stability stable * @category models * @since 4.0.0 */ export interface ConstraintCodec extends Constraint { readonly "Type": T readonly "Encoded": E readonly "DecodingServices": RD readonly "EncodingServices": RE } /** * Lightweight structural constraint for APIs that need decoder type views but * do not need the full schema protocol. * * **When to use** * * Use when you need to preserve a schema's decoded type and decoding services, * but the API does not constrain the encoded type, encoding services, or call * schema methods such as `annotate`, `check`, `rebuild`, `make`, or * `makeEffect`. * * @see {@link ConstraintCodec} for APIs that need both decoded and encoded codec views. * @see {@link Codec} for the full schema protocol with codec type views. * * @stability stable * @category models * @since 4.0.0 */ export interface ConstraintDecoder extends ConstraintCodec {} /** * Lightweight structural constraint for APIs that need encoder type views but * do not need the full schema protocol. * * **When to use** * * Use when you need to preserve a schema's encoded type and encoding services, * but the API does not constrain the decoded type, decoding services, or call * schema methods such as `annotate`, `check`, `rebuild`, `make`, or * `makeEffect`. * * @see {@link ConstraintCodec} for APIs that need both decoded and encoded codec views. * @see {@link Codec} for the full schema protocol with codec type views. * * @stability stable * @category models * @since 4.0.0 */ export interface ConstraintEncoder extends ConstraintCodec {} /** * Lightweight structural constraint for APIs that need schema views and the * rebuilt schema type, but do not call the full schema protocol. * * **When to use** * * Use when an API needs to read `Rebuild` in addition to the schema views * exposed by {@link Constraint}, but does not call methods such as `annotate`, * `check`, `rebuild`, `make`, or `makeEffect`. * * @stability stable * @category models * @since 4.0.0 */ export interface ConstraintRebuildable extends Constraint { readonly "Rebuild": Constraint } /** * Namespace of type-level helpers for {@link Schema}. * * @stability stable * @since 3.10.0 */ export declare namespace Schema { /** * Extracts the decoded `Type` from a schema. * * **Example** (Extracting the decoded type) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const Person = Schema.Struct({ name: Schema.String, age: Schema.Number }) * type Person = Schema.Schema.Type * // { readonly name: string; readonly age: number } * ``` * * @category utility types * @since 3.10.0 */ type Type = S extends { readonly "Type": infer T } ? T : never } /** * A typed view of a schema that tracks only the decoded (output) type `T`. * * **Details** * * Use `Schema` as a constraint when you want to accept "any schema that * decodes to `T`" and do not need to know or constrain the encoded * representation, required services, or any other type parameters. * * This is a structural interface — concrete schema values are produced by the * constructors in this module (e.g. {@link Struct}, {@link String}, {@link Number}). * When you also need the encoded type or service requirements, use {@link Codec}. * * **Example** (Accepting any schema decoding to `string`) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const accept = (_schema: Schema.Schema): void => {} * * accept(Schema.String) * accept(Schema.NonEmptyString) * ``` * * @see {@link Codec} — also tracks Encoded, DecodingServices, EncodingServices * @see {@link Schema.Type} — extract the decoded type at the type level * * @stability stable * @category models * @since 3.10.0 */ export interface Schema extends Top { readonly "Type": T readonly "Rebuild": Schema } /** * Namespace of type-level helpers for {@link Codec}. * * @stability stable * @since 4.0.0 */ export declare namespace Codec { /** * Extracts the encoded (`Encoded`) type from a schema. * * **Example** (Extracting the encoded type) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.NumberFromString * type Enc = Schema.Codec.Encoded * // string * ``` * * @category utility types * @since 3.10.0 */ type Encoded = S extends { readonly "Encoded": infer E } ? E : never /** * Extracts the Effect services required during *decoding* from a schema. * * **Example** (Checking decoding service requirements) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.String * type RD = Schema.Codec.DecodingServices * // never * ``` * * @category utility types * @since 4.0.0 */ type DecodingServices = S extends { readonly "DecodingServices": infer R } ? R : never /** * Extracts the Effect services required during *encoding* from a schema. * * **Example** (Checking encoding service requirements) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.String * type RE = Schema.Codec.EncodingServices * // never * ``` * * @category utility types * @since 4.0.0 */ type EncodingServices = S extends { readonly "EncodingServices": infer R } ? R : never } /** * A schema that tracks the decoded type `T`, the encoded type `E`, and the * Effect services required during decoding (`RD`) and encoding (`RE`). * * **Details** * * Use `Codec` when you need to preserve full type information * about a schema — both what it decodes to and what it serializes from/to. * Most concrete schemas produced by this module implement `Codec`. * * For APIs that only need one direction, prefer the narrower views: * - {@link Decoder}`` — decode-only * - {@link Encoder}`` — encode-only * - {@link Schema}`` — type-only (no encoded representation) * * **Example** (Accepting a codec that decodes to `number` from `string`) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const serialize = (codec: Schema.Codec, value: T): string => * Schema.encodeSync(codec)(value) * * serialize(Schema.NumberFromString, 42) // => "42" * ``` * * @see {@link Codec.Encoded} — extract the encoded type * @see {@link Codec.DecodingServices} — extract required decoding services * @see {@link Codec.EncodingServices} — extract required encoding services * @see {@link revealCodec} — helper to make TypeScript infer the full Codec type * * @stability stable * @category models * @since 4.0.0 */ export interface Codec extends Schema { readonly "Encoded": E readonly "DecodingServices": RD readonly "EncodingServices": RE readonly "Rebuild": Codec } /** * A schema that tracks the decoded type `T` and the Effect services required * during decoding (`RD`). * * **When to use** * * Use when you need to preserve a schema's decoded type and decoding service * requirements, but do not need to constrain its encoded representation or * encoding services. * * @see {@link Codec} for preserving both decoded and encoded type information. * @see {@link Encoder} for the encode-only view. * * @stability stable * @category models * @since 4.0.0 */ export interface Decoder extends Schema { readonly "Encoded": unknown readonly "DecodingServices": RD readonly "EncodingServices": unknown readonly "Rebuild": Decoder } /** * A schema that tracks the encoded type `E` and the Effect services required * during encoding (`RE`). * * **When to use** * * Use when you need to preserve a schema's encoded type and encoding service * requirements, but do not need to constrain its decoded representation or * decoding services. * * @see {@link Codec} for preserving both decoded and encoded type information. * @see {@link Decoder} for the decode-only view. * * @stability stable * @category models * @since 4.0.0 */ export interface Encoder extends Schema { readonly "Encoded": E readonly "DecodingServices": unknown readonly "EncodingServices": RE readonly "Rebuild": Encoder } /** * Returns a codec widened to the full {@link Codec} interface, prompting * TypeScript to infer all four type parameters (`T`, `E`, `RD`, `RE`). * * **Details** * * When a schema is stored in a variable typed as `Schema` or `Top`, the * encoded type and service requirements are erased. Passing the value through * `revealCodec` recovers those parameters without any runtime cost. * * **Example** (Recovering encoded type from a schema variable) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema: Schema.Schema = Schema.NumberFromString * * // Without revealCodec, Encoded is unknown * const codec = Schema.revealCodec(schema) * type Enc = typeof codec["Encoded"] // string * ``` * * @stability stable * @category utility types * @since 4.0.0 */ export function revealCodec(codec: Codec) { return codec } /** * A schema that additionally supports optic (lens/prism) operations. * * **Details** * * `Optic` extends {@link Schema}`` with an `Iso` type that * describes the isomorphic counterpart used by the optic layer. Crucially, * decoding and encoding require *no* Effect services (`DecodingServices` and * `EncodingServices` are both `never`), which means the optic can operate * purely without an Effect runtime. * * Most primitive schemas (e.g. `Schema.String`, `Schema.Number`) implement * `Optic` automatically. You normally interact with this interface through * {@link Optic_} utilities rather than constructing it directly. * * @stability stable * @category models * @since 4.0.0 */ export interface Optic extends Schema { readonly "Iso": Iso readonly "DecodingServices": never readonly "EncodingServices": never readonly "Rebuild": Optic } /** * Error thrown or returned when schema decoding or encoding fails. * * **Details** * * The `issue` field contains a structured {@link SchemaIssue.Issue} tree describing * every validation failure, including the path to the problematic value and * the expected type or constraint. The `message` field renders the issue tree * with the default formatter. * * **Gotchas** * * Parsing with `reportInput: true` adds an enumerable `input` field to * value-bearing issues. Built-in messages may include reported input, and * custom annotations or messages are not sanitized. * * **Example** (Inspecting a SchemaError) * * ```ts import.meta.vitest * import { Result, Schema } from "effect" * * const result = Schema.decodeUnknownResult(Schema.Number)("not a number") * const message = Result.isFailure(result) ? result.failure.message : "" * message // => "Expected number" * ``` * * @see {@link isSchemaError} for narrowing unknown values * @stability stable * @category errors * @since 4.0.0 */ export class SchemaError extends Data.TaggedError("SchemaError")<{ readonly issue: SchemaIssue.Issue }> { readonly [SchemaErrorTypeId]: typeof SchemaErrorTypeId = SchemaErrorTypeId constructor(issue: SchemaIssue.Issue) { const stackTraceLimit = getStackTraceLimit() setStackTraceLimit(0) try { super({ issue }) } finally { setStackTraceLimit(stackTraceLimit) } } override get message() { return SchemaIssue.defaultFormatter(this.issue) } override toJSON() { return { _tag: this._tag, message: this.message } } override [NodeInspectSymbol]() { return this.toJSON() } override toString() { return `SchemaError(${this.message})` } } /** * Returns `true` if `u` is a {@link SchemaError}. * * **When to use** * * Use when you need to narrow an unknown value to `SchemaError`. * * **Example** (Narrowing Schema errors) * * ```ts import.meta.vitest * import { Result, Schema } from "effect" * * const result = Result.try(() => Schema.decodeUnknownSync(Schema.Number)("oops")) * const error: unknown = Result.isFailure(result) ? result.failure : undefined * Schema.isSchemaError(error) // => true * ``` * * @stability stable * @category guards * @since 4.0.0 */ export function isSchemaError(u: unknown): u is SchemaError { return isSchemaErrorInternal(u) } function fromIssueEffect( self: Effect.Effect ): Effect.Effect { if (effectIsExit(self)) { return fromIssueExit(self as Exit_.Exit) } return Effect.catchCause( self, (cause) => Effect.failCauseSync(() => Cause_.map(cause, (issue) => new SchemaError(issue))) ) } function fromIssueExit(exit: Exit_.Exit): Exit_.Exit { return Exit_.isSuccess(exit) ? exit as unknown as Exit_.Exit : Exit_.failCause(Cause_.map(exit.cause, (issue) => new SchemaError(issue))) } function getSchemaErrorOrThrow( cause: Cause_.Cause, message: string ): SchemaError { let schemaError: SchemaError | undefined for (const reason of cause.reasons) { if (!Cause_.isFailReason(reason) || !isSchemaError(reason.error)) { throw new globalThis.Error(message, { cause }) } schemaError ??= reason.error } if (schemaError === undefined) { throw new globalThis.Error(message, { cause }) } return schemaError } function runSchemaErrorPromise( self: Effect.Effect ): Promise { return Effect.runPromiseExit(self).then((exit) => { if (Exit_.isSuccess(exit)) { return exit.value } throw getSchemaErrorOrThrow(exit.cause, "Promise adapter can only reject schema errors") }) } function runSchemaErrorSync( self: Effect.Effect ): A { const exit = Effect.runSyncExit(self) if (Exit_.isSuccess(exit)) { return exit.value } throw getSchemaErrorOrThrow(exit.cause, "Sync adapter can only throw schema errors") } /** * Returns a "Standard Schema" object conforming to the [Standard Schema * v1](https://standardschema.dev/) specification. * * **Details** * * This function creates a schema whose `validate` method attempts to decode and * validate the provided input synchronously. If the underlying `Schema` * includes any asynchronous components (e.g., asynchronous message resolutions * or checks), then validation will necessarily return a `Promise` instead. * * **Example** (Creating a standard schema from a regular schema) * * ```ts import.meta.vitest * import { Schema } from "effect" * * // Define custom hook functions for error formatting * const leafHook = (issue: any) => { * switch (issue._tag) { * case "InvalidType": * return "Expected different type" * case "InvalidValue": * return "Invalid value provided" * case "MissingKey": * return "Required property missing" * case "UnexpectedKey": * return "Unexpected property found" * case "Forbidden": * return "Operation not allowed" * case "OneOf": * return "Multiple valid options available" * default: * return "Validation error" * } * } * * // Create a standard schema from a regular schema * const PersonSchema = Schema.Struct({ * name: Schema.NonEmptyString, * age: Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 150 })) * }) * * const standardSchema = Schema.toStandardSchemaV1(PersonSchema, { * leafHook * }) * * // The standard schema can be used with any Standard Schema v1 compatible library * const validResult = standardSchema["~standard"].validate({ * name: "Alice", * age: 30 * }) * const invalidResult = standardSchema["~standard"].validate({ * name: "", * age: 200 * }) * * if (validResult instanceof Promise || invalidResult instanceof Promise) { * throw new Error("Expected synchronous validation") * } * if ("value" in validResult) { * validResult.value // => { name: "Alice", age: 30 } * } * invalidResult.issues?.map((issue) => issue.path) // => [["name"], ["age"]] * ``` * * @stability stable * @category converting * @since 4.0.0 */ export function toStandardSchemaV1>( self: S, options?: { readonly leafHook?: SchemaIssue.LeafHook | undefined readonly checkHook?: SchemaIssue.CheckHook | undefined readonly parseOptions?: SchemaAST.ParseOptions | undefined } ): StandardSchemaV1 & S { return InternalStandardSchema.toStandardSchemaV1(self, options) } /** * Converts a schema to an experimental Standard JSON Schema V1 representation. * * **Details** * * https://github.com/standard-schema/standard-schema/pull/134 * * @stability stable * @category converting * @since 4.0.0 */ export function toStandardJSONSchemaV1( self: S ): StandardJSONSchemaV1 & S { return InternalStandardSchema.toStandardJSONSchemaV1(self) } /** * Creates a type guard function that checks if a value conforms to a given * schema. * * **Details** * * This function returns a predicate that performs a type-safe check, narrowing * the type of the input value if the check passes. The predicate returns `false` * for schema mismatches. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `false`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * **Example** (Defining a basic type guard) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const isString = Schema.is(Schema.String) * * isString("hello") // => true * isString(42) // => false * * // Type narrowing in action * const value: unknown = "hello" * if (isString(value)) { * // value is now typed as string * value.toUpperCase() // => "HELLO" * } * ``` * * @stability stable * @category guards * @since 3.10.0 */ export const is: typeof SchemaParser.is = SchemaParser.is /** * Creates an assertion function that throws an error if the input does not match * the schema. * * **When to use** * * Use to validate unknown input at runtime while narrowing the value with a * TypeScript assertion signature. * * **Details** * * The input is narrowed if the assertion succeeds. If schema validation fails, * the assertion throws an `Error` whose cause is `SchemaIssue.Issue`. * Schema validation failures use the generic message `"Schema validation failed"`. * Format the `cause` explicitly with `SchemaIssue.makeFormatterDefault()` when * human-readable details are needed. * * **Gotchas** * * Causes that contain defects, interruptions, or other non-schema reasons throw * with the underlying `Cause` attached instead of being converted to schema * validation errors. * * **Example** (Asserting and narrowing an input) * * ```ts import.meta.vitest * import { Schema, SchemaIssue } from "effect" * * const input: unknown = "hello" * * // This will pass silently (no return value) and narrow input to string * Schema.asserts(Schema.String, input) * input.toUpperCase() // => "HELLO" * * // This will throw an error * try { * const invalid: unknown = 123 * Schema.asserts(Schema.String, invalid) * } catch (error) { * if (error instanceof Error) { * SchemaIssue.isIssue(error.cause) // => true * } * } * ``` * * @stability stable * @category guards * @since 4.0.0 */ export const asserts: (schema: S, input: I) => asserts input is I & S["Type"] = SchemaParser.asserts /** * Decodes an `unknown` input against a schema, returning an `Effect` that * succeeds with the decoded value or fails with a {@link SchemaError}. * * **When to use** * * Use when you need to decode unknown input in an `Effect` whose failure * channel is `SchemaError`. * * **Details** * * Prefer {@link decodeEffect} when the input is already typed as the schema's * `Encoded` type. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * @see {@link SchemaParser.decodeUnknownEffect} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export function decodeUnknownEffect(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.decodeUnknownEffect(schema, options) return ( input: unknown, options?: SchemaAST.ParseOptions ): Effect.Effect => { return fromIssueEffect(parser(input, options)) } } /** * Decodes a typed input (the schema's `Encoded` type) against a schema, * returning an `Effect` that succeeds with the decoded value or fails with a * {@link SchemaError}. * * **When to use** * * Use when you need to decode input already typed as the schema's `Encoded` * type in an `Effect` whose failure channel is `SchemaError`. * * **Details** * * For `unknown` input use {@link decodeUnknownEffect}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * @see {@link SchemaParser.decodeEffect} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export const decodeEffect: ( schema: S, options?: SchemaAST.ParseOptions ) => ( input: S["Encoded"], options?: SchemaAST.ParseOptions ) => Effect.Effect = decodeUnknownEffect /** * Decodes an `unknown` input against a schema synchronously, returning an * `Exit` that is either a `Success` with the decoded value or a `Failure`. * * **When to use** * * Use when you need to decode unknown input into an `Exit` and capture schema * mismatches as `SchemaError`. * * **Details** * * Only usable with schemas that have no `DecodingServices` requirement. Prefer * {@link decodeExit} when the input is already typed as the schema's `Encoded` * type. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * Schema mismatches are represented by a `Failure` cause containing * `SchemaError`. * * **Gotchas** * * Schema issue fail reasons are wrapped as `SchemaError`. Defects, * interruptions, and other non-schema reasons remain in the returned `Cause`, * including when they are mixed with schema issues. * * @see {@link SchemaParser.decodeUnknownExit} for the adapter whose failure contains `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export function decodeUnknownExit>(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.decodeUnknownExit(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Exit_.Exit => { return fromIssueExit(parser(input, options)) } } /** * Decodes a typed input (the schema's `Encoded` type) against a schema * synchronously, returning an `Exit` that is either a `Success` with the decoded * value or a `Failure`. * * **When to use** * * Use when you need to decode already typed `Encoded` input into an `Exit` and * capture schema mismatches as `SchemaError`. * * **Details** * * Only usable with schemas that have no `DecodingServices` requirement. For * `unknown` input use {@link decodeUnknownExit}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * Schema mismatches are represented by a `Failure` cause containing * `SchemaError`. * * **Gotchas** * * Schema issue fail reasons are wrapped as `SchemaError`. Defects, * interruptions, and other non-schema reasons remain in the returned `Cause`, * including when they are mixed with schema issues. * * @see {@link SchemaParser.decodeExit} for the adapter whose failure contains `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export const decodeExit: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Encoded"], options?: SchemaAST.ParseOptions) => Exit_.Exit = decodeUnknownExit /** * Decodes an `unknown` input against a schema, returning an `Option` that is * `Some` with the decoded value on success or `None` for schema mismatches. * * **When to use** * * Use when you do not know the input type statically and only need to know * whether decoding succeeded. * * **Details** * * Prefer this over {@link decodeUnknownExit} or {@link decodeUnknownEffect} * when you don't need error details. For input already typed as the schema's * `Encoded` type use {@link decodeOption}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `None`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * @stability stable * @category decoding * @since 3.10.0 */ export const decodeUnknownOption: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: unknown, options?: SchemaAST.ParseOptions) => Option_.Option = SchemaParser.decodeUnknownOption /** * Decodes a typed input (the schema's `Encoded` type) against a schema, * returning an `Option` that is `Some` with the decoded value on success or * `None` for schema mismatches. * * **When to use** * * Use when you already have input typed as the schema's `Encoded` type and * only need to know whether decoding succeeded. * * **Details** * * For `unknown` input use {@link decodeUnknownOption}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `None`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * @stability stable * @category decoding * @since 3.10.0 */ export const decodeOption: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Encoded"], options?: SchemaAST.ParseOptions) => Option_.Option = SchemaParser.decodeOption /** * Decodes an `unknown` input against a schema, returning a `Result` that * succeeds with the decoded value or fails with a {@link SchemaError} for schema * mismatches. * * **When to use** * * Use when you do not know the input type statically and want schema mismatches * returned as `Result.fail` with `SchemaError`. * * **Details** * * For input already typed as the schema's `Encoded` type use * {@link decodeResult}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * Schema mismatches are returned as `Result.fail` with `SchemaError`. * * **Gotchas** * * Only causes made entirely of schema issues are returned as `Result.fail`. * Causes that contain defects, interruptions, or other non-schema reasons throw * instead. * * @see {@link SchemaParser.decodeUnknownResult} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export function decodeUnknownResult>(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.decodeUnknownResult(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Result_.Result => { return Result_.mapError(parser(input, options), (issue) => new SchemaError(issue)) } } /** * Decodes a typed input (the schema's `Encoded` type) against a schema, * returning a `Result` that succeeds with the decoded value or fails with a * {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you already have input typed as the schema's `Encoded` type and want * schema mismatches returned as `Result.fail` with `SchemaError`. * * **Details** * * For `unknown` input use {@link decodeUnknownResult}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * Schema mismatches are returned as `Result.fail` with `SchemaError`. * * **Gotchas** * * Only causes made entirely of schema issues are returned as `Result.fail`. * Causes that contain defects, interruptions, or other non-schema reasons throw * instead. * * @see {@link SchemaParser.decodeResult} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category decoding * @since 4.0.0 */ export const decodeResult: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Encoded"], options?: SchemaAST.ParseOptions) => Result_.Result = decodeUnknownResult /** * Decodes an `unknown` input against a schema, returning a `Promise` that * resolves with the decoded value or rejects with a {@link SchemaError} for * schema mismatches. * * **When to use** * * Use when you need decoding of unknown input to return a JavaScript `Promise` * that rejects with `SchemaError` for schema mismatches. * * **Details** * * For input already typed as the schema's `Encoded` type use * {@link decodePromise}. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * **Gotchas** * * Non-schema failures may reject with a runtime failure instead of * `SchemaError`. * * @see {@link SchemaParser.decodeUnknownPromise} for the adapter that rejects with an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category decoding * @since 3.10.0 */ export function decodeUnknownPromise>( schema: S, options?: SchemaAST.ParseOptions ) { const parser = decodeUnknownEffect(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Promise => { return runSchemaErrorPromise(parser(input, options)) } } /** * Decodes a typed input (the schema's `Encoded` type) against a schema, * returning a `Promise` that resolves with the decoded value or rejects with a * {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you already have input typed as the schema's `Encoded` type and * need decoding to return a JavaScript `Promise` that rejects with * `SchemaError` for schema mismatches. * * **Details** * * For `unknown` input use `decodeUnknownPromise`. * Options may be provided either when creating the decoder or when applying it; * application options override creation options. * * **Gotchas** * * Non-schema failures may reject with a runtime failure instead of * `SchemaError`. * * @see {@link SchemaParser.decodePromise} for the adapter that rejects with an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category decoding * @since 3.10.0 */ export const decodePromise: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Encoded"], options?: SchemaAST.ParseOptions) => Promise = decodeUnknownPromise /** * Decodes an `unknown` input against a schema synchronously, returning the * decoded value or throwing a {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you need to validate unknown data at a synchronous boundary and want * schema mismatches to throw `SchemaError`. * * **Details** * * For input already typed as the schema's `Encoded` type use `decodeSync`. * Only service-free schemas can be decoded synchronously. For alternatives that * do not throw on schema mismatches, see `decodeUnknownOption`, * `decodeUnknownExit`, or `decodeUnknownEffect`. Options may be provided either * when creating the decoder or when applying it; application options override * creation options. * * **Gotchas** * * Non-schema failures may throw a runtime failure instead of `SchemaError`. * * **Example** (Decoding with a transformation schema) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const NumberFromString = Schema.NumberFromString * * Schema.decodeUnknownSync(NumberFromString)("42") // => 42 * ``` * * @see {@link SchemaParser.decodeUnknownSync} for the adapter that throws an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category decoding * @since 4.0.0 */ export function decodeUnknownSync>(schema: S, options?: SchemaAST.ParseOptions) { const parser = decodeUnknownEffect(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): S["Type"] => { return runSchemaErrorSync(parser(input, options)) } } /** * Decodes a typed input (the schema's `Encoded` type) against a schema * synchronously, returning the decoded value or throwing a {@link SchemaError} * for schema mismatches. * * **When to use** * * Use when you already have input typed as the schema's `Encoded` type and * want schema mismatches to throw `SchemaError` synchronously. * * **Details** * * For `unknown` input use `decodeUnknownSync`. * Only service-free schemas can be decoded synchronously. Options may be * provided either when creating the decoder or when applying it; application * options override creation options. * * **Gotchas** * * Non-schema failures may throw a runtime failure instead of `SchemaError`. * * @see {@link SchemaParser.decodeSync} for the adapter that throws an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category decoding * @since 4.0.0 */ export const decodeSync: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Encoded"], options?: SchemaAST.ParseOptions) => S["Type"] = decodeUnknownSync /** * Encodes an `unknown` input against a schema, returning an `Effect` that * succeeds with the encoded value or fails with a {@link SchemaError}. * * **When to use** * * Use when you need to encode unknown input in an `Effect` whose failure * channel is `SchemaError`. * * **Details** * * Prefer {@link encodeEffect} when the value is already typed as the schema's * `Type`. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Example** (Encoding a value to a string) * * ```ts import.meta.vitest * import { Effect, Schema } from "effect" * * const NumberFromString = Schema.NumberFromString * * await Effect.runPromise(Schema.encodeUnknownEffect(NumberFromString)(42)) // => "42" * ``` * * @see {@link SchemaParser.encodeUnknownEffect} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export function encodeUnknownEffect(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.encodeUnknownEffect(schema, options) return ( input: unknown, options?: SchemaAST.ParseOptions ): Effect.Effect => { return fromIssueEffect(parser(input, options)) } } /** * Encodes a typed input (the schema's `Type`) against a schema, returning an * `Effect` that succeeds with the encoded value or fails with a * {@link SchemaError}. * * **When to use** * * Use when you need to encode input already typed as the schema's `Type` in * an `Effect` whose failure channel is `SchemaError`. * * **Details** * * For `unknown` input use {@link encodeUnknownEffect}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * @see {@link SchemaParser.encodeEffect} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export const encodeEffect: ( schema: S, options?: SchemaAST.ParseOptions ) => ( input: S["Type"], options?: SchemaAST.ParseOptions ) => Effect.Effect = encodeUnknownEffect /** * Encodes an `unknown` input against a schema synchronously, returning an * `Exit` that is either a `Success` with the encoded value or a `Failure`. * * **When to use** * * Use when you need to encode unknown input into an `Exit` and capture schema * mismatches as `SchemaError`. * * **Details** * * Only usable with schemas that have no `EncodingServices` requirement. Prefer * {@link encodeExit} when the value is already typed as the schema's `Type`. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * Schema mismatches are represented by a `Failure` cause containing * `SchemaError`. * * **Gotchas** * * Schema issue fail reasons are wrapped as `SchemaError`. Defects, * interruptions, and other non-schema reasons remain in the returned `Cause`, * including when they are mixed with schema issues. * * @see {@link SchemaParser.encodeUnknownExit} for the adapter whose failure contains `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export function encodeUnknownExit>(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.encodeUnknownExit(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Exit_.Exit => { return fromIssueExit(parser(input, options)) } } /** * Encodes a typed input (the schema's `Type`) against a schema synchronously, * returning an `Exit` that is either a `Success` with the encoded value or a * `Failure`. * * **When to use** * * Use when you need to encode already typed schema values into an `Exit` and * capture schema mismatches as `SchemaError`. * * **Details** * * Only usable with schemas that have no `EncodingServices` requirement. For * `unknown` input use {@link encodeUnknownExit}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * Schema mismatches are represented by a `Failure` cause containing * `SchemaError`. * * **Gotchas** * * Schema issue fail reasons are wrapped as `SchemaError`. Defects, * interruptions, and other non-schema reasons remain in the returned `Cause`, * including when they are mixed with schema issues. * * @see {@link SchemaParser.encodeExit} for the adapter whose failure contains `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export const encodeExit: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Type"], options?: SchemaAST.ParseOptions) => Exit_.Exit = encodeUnknownExit /** * Encodes an `unknown` input against a schema, returning an `Option` that is * `Some` with the encoded value on success or `None` for schema mismatches. * * **When to use** * * Use when you do not know the input type statically and only need to know * whether encoding succeeded. * * **Details** * * Prefer this over {@link encodeUnknownExit} or {@link encodeUnknownEffect} * when you don't need error details. For values already typed as the schema's * `Type` use {@link encodeOption}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `None`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * @stability stable * @category encoding * @since 3.10.0 */ export const encodeUnknownOption: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: unknown, options?: SchemaAST.ParseOptions) => Option_.Option = SchemaParser.encodeUnknownOption /** * Encodes a typed input (the schema's `Type`) against a schema, returning an * `Option` that is `Some` with the encoded value on success or `None` for schema * mismatches. * * **When to use** * * Use when you already have a value typed as the schema's `Type` and only need * to know whether encoding succeeded. * * **Details** * * For `unknown` input use {@link encodeUnknownOption}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Gotchas** * * Only causes made entirely of schema issues are converted to `None`. Causes * that contain defects, interruptions, or other non-schema reasons throw * instead. * * @stability stable * @category encoding * @since 3.10.0 */ export const encodeOption: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Type"], options?: SchemaAST.ParseOptions) => Option_.Option = SchemaParser.encodeOption /** * Encodes an `unknown` input against a schema, returning a `Result` that * succeeds with the encoded value or fails with a {@link SchemaError} for schema * mismatches. * * **When to use** * * Use when you do not know the input type statically and want schema mismatches * returned as `Result.fail` with `SchemaError`. * * **Details** * * For values already typed as the schema's `Type` use {@link encodeResult}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * Schema mismatches are returned as `Result.fail` with `SchemaError`. * * **Gotchas** * * Only causes made entirely of schema issues are returned as `Result.fail`. * Causes that contain defects, interruptions, or other non-schema reasons throw * instead. * * @see {@link SchemaParser.encodeUnknownResult} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export function encodeUnknownResult>(schema: S, options?: SchemaAST.ParseOptions) { const parser = SchemaParser.encodeUnknownResult(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Result_.Result => { return Result_.mapError(parser(input, options), (issue) => new SchemaError(issue)) } } /** * Encodes a typed input (the schema's `Type`) against a schema, returning a * `Result` that succeeds with the encoded value or fails with a * {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you already have a value typed as the schema's `Type` and want schema * mismatches returned as `Result.fail` with `SchemaError`. * * **Details** * * For `unknown` input use {@link encodeUnknownResult}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * Schema mismatches are returned as `Result.fail` with `SchemaError`. * * **Gotchas** * * Only causes made entirely of schema issues are returned as `Result.fail`. * Causes that contain defects, interruptions, or other non-schema reasons throw * instead. * * @see {@link SchemaParser.encodeResult} for the adapter that fails with `SchemaIssue.Issue` directly * * @stability stable * @category encoding * @since 4.0.0 */ export const encodeResult: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Type"], options?: SchemaAST.ParseOptions) => Result_.Result = encodeUnknownResult /** * Encodes an `unknown` input against a schema, returning a `Promise` that * resolves with the encoded value or rejects with a {@link SchemaError} for * schema mismatches. * * **When to use** * * Use when you need encoding of unknown input to return a JavaScript `Promise` * that rejects with `SchemaError` for schema mismatches. * * **Details** * * For values already typed as the schema's `Type` use {@link encodePromise}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Gotchas** * * Non-schema failures may reject with a runtime failure instead of * `SchemaError`. * * @see {@link SchemaParser.encodeUnknownPromise} for the adapter that rejects with an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category encoding * @since 3.10.0 */ export function encodeUnknownPromise>( schema: S, options?: SchemaAST.ParseOptions ) { const parser = encodeUnknownEffect(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): Promise => { return runSchemaErrorPromise(parser(input, options)) } } /** * Encodes a typed input (the schema's `Type`) against a schema, returning a * `Promise` that resolves with the encoded value or rejects with a * {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you already have a value typed as the schema's `Type` and need * encoding to return a JavaScript `Promise` that rejects with `SchemaError` for * schema mismatches. * * **Details** * * For `unknown` input use {@link encodeUnknownPromise}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Gotchas** * * Non-schema failures may reject with a runtime failure instead of * `SchemaError`. * * @see {@link SchemaParser.encodePromise} for the adapter that rejects with an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category encoding * @since 3.10.0 */ export const encodePromise: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Type"], options?: SchemaAST.ParseOptions) => Promise = encodeUnknownPromise /** * Encodes an `unknown` input against a schema synchronously, throwing a * {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you need to serialize unknown data at a synchronous boundary and * want schema mismatches to throw `SchemaError`. * * **Details** * * For alternatives that do not throw on schema mismatches, see * {@link encodeUnknownOption}, {@link encodeUnknownExit}, or * {@link encodeUnknownEffect}. For values already typed as the schema's `Type` * use {@link encodeSync}. Options may be provided either when creating the * encoder or when applying it; application options override creation options. * * **Gotchas** * * Non-schema failures may throw a runtime failure instead of `SchemaError`. * * @see {@link SchemaParser.encodeUnknownSync} for the adapter that throws an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category encoding * @since 4.0.0 */ export function encodeUnknownSync>(schema: S, options?: SchemaAST.ParseOptions) { const parser = encodeUnknownEffect(schema, options) return (input: unknown, options?: SchemaAST.ParseOptions): S["Encoded"] => { return runSchemaErrorSync(parser(input, options) as Effect.Effect) } } /** * Encodes a typed input (the schema's `Type`) against a schema synchronously, * throwing a {@link SchemaError} for schema mismatches. * * **When to use** * * Use when you already have a value typed as the schema's `Type` and want * schema mismatches to throw `SchemaError` synchronously. * * **Details** * * For `unknown` input use {@link encodeUnknownSync}. * Options may be provided either when creating the encoder or when applying it; * application options override creation options. * * **Gotchas** * * Non-schema failures may throw a runtime failure instead of `SchemaError`. * * @see {@link SchemaParser.encodeSync} for the adapter that throws an `Error` whose cause is `SchemaIssue.Issue` * * @stability stable * @category encoding * @since 4.0.0 */ export const encodeSync: >( schema: S, options?: SchemaAST.ParseOptions ) => (input: S["Type"], options?: SchemaAST.ParseOptions) => S["Encoded"] = encodeUnknownSync /** * Creates a schema from an AST (Abstract Syntax Tree) node. * * **Details** * * This is the fundamental constructor for all schemas in the Effect Schema * library. It takes an AST node and wraps it in a fully-typed schema that * preserves all type information and provides the complete schema API. * * The `make` function is used internally to create all primitive schemas like * `String`, `Number`, `Boolean`, etc., as well as more complex schemas. It's * the bridge between the untyped AST representation and the strongly-typed * schema. * * @stability stable * @category constructors * @since 3.10.0 */ export const make: (ast: S["ast"], options?: object) => S = InternalMake.make /** * Checks whether a value is a `Schema`. * * @stability stable * @category guards * @since 3.10.0 */ export function isSchema(u: unknown): u is Top { return Predicate.hasProperty(u, TypeId) && u[TypeId] === TypeId } /** * Type-level representation returned by {@link optionalKey}. * * @stability stable * @category models * @since 4.0.0 */ export interface optionalKey extends BottomLazy< S["ast"], optionalKey, S["~type.parameters"], S["~type.mutability"], "optional", S["~type.constructor.default"], S["~encoded.mutability"], "optional" > { readonly "Type": S["Type"] readonly "Encoded": S["Encoded"] readonly "DecodingServices": S["DecodingServices"] readonly "EncodingServices": S["EncodingServices"] readonly "~type.make.in": S["~type.make.in"] readonly "~type.make": S["~type.make"] readonly "Iso": S["Iso"] readonly schema: S } interface optionalKeyLambda extends Lambda { (self: S): optionalKey readonly "~lambda.out": this["~lambda.in"] extends Constraint ? optionalKey : never } /** * Creates an exact optional key schema for struct fields. Unlike `optional`, * this creates exact optional properties (not `| undefined`) that can be * completely omitted from the object. * * **Example** (Creating a struct with optional key) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.Struct({ * name: Schema.String, * age: Schema.optionalKey(Schema.Number) * }) * * // Type: { readonly name: string; readonly age?: number } * type Person = typeof schema["Type"] * ``` * * @stability stable * @category combinators * @since 4.0.0 */ export const optionalKey: optionalKeyLambda = Struct_.lambda((schema) => make(SchemaAST.optionalKey(schema.ast), { schema }) ) interface requiredKeyLambda extends Lambda { (self: optionalKey): S readonly "~lambda.out": this["~lambda.in"] extends optionalKey ? this["~lambda.in"]["schema"] : "Error: schema not eligible for requiredKey" } /** * Reverses `optionalKey` and returns the inner required schema. * * **When to use** * * Use to remove optional-key wrapping from a schema field that was previously * wrapped with {@link optionalKey}. * * @stability stable * @category combinators * @since 4.0.0 */ export const requiredKey: requiredKeyLambda = Struct_.lambda((self) => self.schema) /** * Type-level representation returned by {@link optional}. * * @stability stable * @category models * @since 3.10.0 */ export interface optional extends optionalKey> { readonly "Rebuild": optional } interface optionalLambda extends Lambda { (self: S): optional readonly "~lambda.out": this["~lambda.in"] extends Constraint ? optional : never } /** * 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 {@link optionalKey} instead if you want exact optional semantics (absent * only, not `undefined`). * * **Example** (Defining an optional field accepting undefined) * * ```ts import.meta.vitest * 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 * ``` * * @stability stable * @category combinators * @since 3.10.0 */ export const optional: optionalLambda = Struct_.lambda((self) => { const schema = UndefinedOr(self) return make(SchemaAST.optional(self.ast), { schema }) }) interface requiredLambda extends Lambda { (self: optional): S readonly "~lambda.out": this["~lambda.in"] extends optional ? this["~lambda.in"]["schema"]["members"][0] : "Error: schema not eligible for required" } /** * Reverses `optional` and returns the inner schema. * * **When to use** * * Use to remove optional wrapping from a schema field that was previously * wrapped with {@link optional}. * * **Details** * * This also unwraps the `UndefinedOr` member added by `optional`. * * @stability stable * @category combinators * @since 3.10.0 */ export const required: requiredLambda = Struct_.lambda((self) => self.schema.members[0]) /** * Type-level representation returned by {@link mutableKey}. * * @stability stable * @category models * @since 4.0.0 */ export interface mutableKey extends BottomLazy< S["ast"], mutableKey, S["~type.parameters"], "mutable", S["~type.optionality"], S["~type.constructor.default"], "mutable", S["~encoded.optionality"] > { readonly "Type": S["Type"] readonly "Encoded": S["Encoded"] readonly "DecodingServices": S["DecodingServices"] readonly "EncodingServices": S["EncodingServices"] readonly "~type.make.in": S["~type.make.in"] readonly "~type.make": S["~type.make"] readonly "Iso": S["Iso"] readonly schema: S } interface mutableKeyLambda extends Lambda { (self: S): mutableKey readonly "~lambda.out": this["~lambda.in"] extends Constraint ? mutableKey : never } /** * Makes a struct field mutable (removes the `readonly` modifier on the property). * Use {@link readonlyKey} to reverse. * * @stability stable * @category combinators * @since 4.0.0 */ export const mutableKey: mutableKeyLambda = Struct_.lambda((schema) => make(SchemaAST.mutableKey(schema.ast), { schema }) ) interface readonlyKeyLambda extends Lambda { (self: mutableKey): S readonly "~lambda.out": this["~lambda.in"] extends mutableKey ? this["~lambda.in"]["schema"] : "Error: schema not eligible for readonlyKey" } /** * Reverses `mutableKey` and returns the inner readonly schema. * * **When to use** * * Use to remove mutable-key wrapping from a schema field that was previously * wrapped with {@link mutableKey}. * * @stability stable * @category combinators * @since 4.0.0 */ export const readonlyKey: readonlyKeyLambda = Struct_.lambda((self) => self.schema) /** * Type-level representation returned by {@link toType}. * * @stability stable * @category transforming * @since 4.0.0 */ export interface toType extends BottomLazy< S["ast"], toType, S["~type.parameters"], S["~type.mutability"], S["~type.optionality"], S["~type.constructor.default"], S["~encoded.mutability"], S["~encoded.optionality"] > { readonly "Type": S["Type"] readonly "Encoded": S["Type"] readonly "DecodingServices": never readonly "EncodingServices": never readonly "~type.make.in": S["~type.make.in"] readonly "~type.make": S["~type.make"] readonly "Iso": S["Iso"] readonly schema: S } interface toTypeLambda extends Lambda { (self: S): toType readonly "~lambda.out": this["~lambda.in"] extends Constraint ? toType : never } /** * Extracts the type-side schema: sets `Encoded` to equal the decoded `Type`, * discarding the encoding transformation path. * * @stability stable * @category transforming * @since 4.0.0 */ export const toType: toTypeLambda = Struct_.lambda((schema) => make(SchemaAST.toType(schema.ast), { schema }) ) /** * Type-level representation returned by {@link toEncoded}. * * @stability stable * @category transforming * @since 4.0.0 */ export interface toEncoded extends BottomLazy< SchemaAST.AST, toEncoded, ReadonlyArray, S["~type.mutability"], S["~type.optionality"], S["~type.constructor.default"], S["~encoded.mutability"], S["~encoded.optionality"] > { readonly "Type": S["Encoded"] readonly "Encoded": S["Encoded"] readonly "DecodingServices": never readonly "EncodingServices": never readonly "~type.make.in": S["Encoded"] readonly "~type.make": S["Encoded"] readonly "Iso": S["Encoded"] readonly schema: S } interface toEncodedLambda extends Lambda { (self: S): toEncoded readonly "~lambda.out": this["~lambda.in"] extends Constraint ? toEncoded : never } /** * Extracts the encoded-side schema: sets `Type` to equal the `Encoded`, * discarding the decoding transformation path. * * @stability stable * @category transforming * @since 4.0.0 */ export const toEncoded: toEncodedLambda = Struct_.lambda((schema) => make(SchemaAST.toEncoded(schema.ast), { schema }) ) const FlipTypeId = "~effect/Schema/flip" /** * Type-level representation returned by {@link flip}. * * @stability stable * @category transforming * @since 4.0.0 */ export interface flip extends BottomLazy< SchemaAST.AST, flip, ReadonlyArray, S["~encoded.mutability"], S["~encoded.optionality"], ConstructorDefault, S["~type.mutability"], S["~type.optionality"] > { readonly "Type": S["Encoded"] readonly "Encoded": S["Type"] readonly "DecodingServices": S["EncodingServices"] readonly "EncodingServices": S["DecodingServices"] readonly "~type.make.in": S["Encoded"] readonly "~type.make": S["Encoded"] readonly "Iso": S["Encoded"] readonly [FlipTypeId]: typeof FlipTypeId readonly schema: S } function isFlip$(schema: Top): schema is flip { return Predicate.hasProperty(schema, FlipTypeId) && schema[FlipTypeId] === FlipTypeId } /** * Swaps the decoded and encoded sides of a schema. * * **When to use** * * Use to invert a schema transformation direction. * * **Details** * * Calling `flip` twice returns the original schema. * * **Example** (Flipping a number-from-string schema) * * ```ts import.meta.vitest * import { Schema } from "effect" * * // NumberFromString: decodes string → number * const flipped = Schema.flip(Schema.NumberFromString) * Schema.decodeSync(flipped)(42) // => "42" * ``` * * @stability stable * @category transforming * @since 4.0.0 */ export function flip(schema: S): S extends flip ? F["Rebuild"] : flip export function flip(schema: S): flip { if (isFlip$(schema)) { return schema.schema.rebuild(SchemaAST.flip(schema.ast)) } return make(SchemaAST.flip(schema.ast), { [FlipTypeId]: FlipTypeId, schema }) } /** * Type-level representation returned by {@link Literal}. * * @stability stable * @category models * @since 3.10.0 */ export interface Literal extends Bottom> { readonly literal: L transform(to: L2): decodeTo, Literal> } /** * Creates a schema for a single literal value (string, number, bigint, boolean, or null). * * **Example** (Defining a string literal) * * ```ts import.meta.vitest * import { Schema } from "effect" * * const schema = Schema.Literal("hello") * // Type: Schema.Literal<"hello"> * Schema.decodeSync(schema)("hello") // => "hello" * ``` * * @see {@link Literals} for a schema that represents a union of literals. * @see {@link tag} for a schema that represents a literal value that can be * used as a discriminator field in tagged unions and has a constructor default. * @stability stable * @category constructors * @since 3.10.0 */ export function Literal(literal: L): Literal { const out = make>(new SchemaAST.Literal(literal), { literal, transform(to: L2): decodeTo, Literal> { return out.pipe(decodeTo(Literal(to), { decode: SchemaGetter.transform(() => to), encode: SchemaGetter.transform(() => literal) })) } }) return out } /** * Namespace for {@link TemplateLiteral} helper types. * * @stability stable * @since 3.10.0 */ export declare namespace TemplateLiteral { /** * Constraint for schema parts that can appear inside a `TemplateLiteral`. * * **Details** * * The schema's encoded value must be a `string`, `number`, or `bigint` so it can * be converted into a template literal string segment. * `TemplateLiteral` additionally rejects encodings at runtime; * `TemplateLiteralParser` supports transformed parts. * * @category utility types * @since 4.0.0 */ interface SchemaPart extends Constraint { readonly Encoded: string | number | bigint } /** * Literal value that can be used directly as a part of a `TemplateLiteral`. * * @category utility types * @since 4.0.0 */ type LiteralPart = string | number | bigint /** * A single part of a `TemplateLiteral`, either an interpolated schema part or a * literal `string`, `number`, or `bigint`. * * @category utility types * @since 4.0.0 */ type Part = SchemaPart | LiteralPart /** * Ordered list of parts used to construct a `TemplateLiteral` schema. * * @category utility types * @since 4.0.0 */ type Parts = ReadonlyArray type AppendType