/** * Abstract Syntax Tree (AST) representation for Effect schemas. * * This module defines the runtime data structures that represent schemas. * Most users work with the `Schema` module directly; use `SchemaAST` when you * need to inspect, traverse, or programmatically transform schema definitions. * * ## Mental model * * - **{@link AST}** — discriminated union (`_tag`) of all schema node types * (e.g. `String`, `Objects`, `Union`, `Suspend`) * - **{@link Base}** — abstract base class shared by every node; carries * annotations, checks, encoding chain, and context * - **{@link Encoding}** — a non-empty chain of {@link Link} values describing * how to transform between the decoded (type) and encoded (wire) form * - **{@link Check}** — a validation filter ({@link Filter} or * {@link FilterGroup}) attached to an AST node * - **{@link Context}** — per-property metadata: optionality, mutability, * default values, key annotations * - **Guards** — type-narrowing predicates for each AST variant (e.g. * {@link isString}, {@link isObjects}) * * ## Common tasks * * - Inspect what kind of schema you have → guard functions ({@link isString}, * {@link isObjects}, {@link isUnion}, etc.) * - Get the decoded (type-level) AST → {@link toType} * - Get the encoded (wire-format) AST → {@link toEncoded} * - Swap decode/encode directions → {@link flip} * - Read annotations → {@link resolve}, {@link resolveAt}, * {@link resolveIdentifier} * - Build a transformation between schemas → {@link decodeTo} * - Add regex validation → {@link isPattern} * * ## Gotchas * * - AST nodes are structurally immutable; modification helpers return new * objects via `Object.create`. * - {@link Arrays} represents both tuples and arrays; {@link Objects} * represents both structs and records. * - {@link toType} and {@link toEncoded} are memoized — same input yields * same output reference. * - {@link Suspend} lazily resolves its inner AST via a thunk; the thunk is * memoized on first call. * * ## Quickstart * * **Example** (Inspecting a schema's AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.Struct({ name: Schema.String, age: Schema.Number }) * const ast = schema.ast * * if (SchemaAST.isObjects(ast)) { * console.log(ast.propertySignatures.map(ps => ps.name)) * // ["name", "age"] * } * * const encoded = SchemaAST.toEncoded(ast) * console.log(SchemaAST.isObjects(encoded)) // true * ``` * * ## See also * * - {@link AST} * - {@link toType} * - {@link toEncoded} * - {@link flip} * - {@link resolve} * * @since 4.0.0 */ import type * as Combiner from "./Combiner.ts"; import * as Effect from "./Effect.ts"; import * as Pipeable from "./Pipeable.ts"; import type * as Schema from "./Schema.ts"; import * as Issue from "./SchemaIssue.ts"; import * as Transformation from "./SchemaTransformation.ts"; /** * Discriminated union of all AST node types. * * Every `Schema` has an `.ast` property of this type. Use the guard functions * ({@link isString}, {@link isObjects}, etc.) to narrow to a specific variant, * then access variant-specific fields. * * - All variants share the {@link Base} fields: `annotations`, `checks`, * `encoding`, `context`. * - Discriminate on the `_tag` field (e.g. `"String"`, `"Objects"`, `"Union"`). * * @see {@link Base} * @see {@link isAST} * * @category model * @since 4.0.0 */ export type AST = Declaration | Null | Undefined | Void | Never | Unknown | Any | String | Number | Boolean | BigInt | Symbol | Literal | UniqueSymbol | ObjectKeyword | Enum | TemplateLiteral | Arrays | Objects | Union | Suspend; /** * Returns `true` if the value is an {@link AST} node (any variant). * * Uses the internal `TypeId` brand to distinguish AST nodes from arbitrary * objects. * * @see {@link AST} * * @category Guard * @since 4.0.0 */ export declare function isAST(u: unknown): u is AST; /** * Narrows an {@link AST} to {@link Declaration}. * * @category Guard * @since 4.0.0 */ export declare const isDeclaration: (ast: AST) => ast is Declaration; /** * Narrows an {@link AST} to {@link Null}. * * @category Guard * @since 4.0.0 */ export declare const isNull: (ast: AST) => ast is Null; /** * Narrows an {@link AST} to {@link Undefined}. * * @category Guard * @since 4.0.0 */ export declare const isUndefined: (ast: AST) => ast is Undefined; /** * Narrows an {@link AST} to {@link Void}. * * @category Guard * @since 4.0.0 */ export declare const isVoid: (ast: AST) => ast is Void; /** * Narrows an {@link AST} to {@link Never}. * * @category Guard * @since 4.0.0 */ export declare const isNever: (ast: AST) => ast is Never; /** * Narrows an {@link AST} to {@link Unknown}. * * @category Guard * @since 4.0.0 */ export declare const isUnknown: (ast: AST) => ast is Unknown; /** * Narrows an {@link AST} to {@link Any}. * * @category Guard * @since 4.0.0 */ export declare const isAny: (ast: AST) => ast is Any; /** * Narrows an {@link AST} to {@link String}. * * @category Guard * @since 4.0.0 */ export declare const isString: (ast: AST) => ast is String; /** * Narrows an {@link AST} to {@link Number}. * * @category Guard * @since 4.0.0 */ export declare const isNumber: (ast: AST) => ast is Number; /** * Narrows an {@link AST} to {@link Boolean}. * * @category Guard * @since 4.0.0 */ export declare const isBoolean: (ast: AST) => ast is Boolean; /** * Narrows an {@link AST} to {@link BigInt}. * * @category Guard * @since 4.0.0 */ export declare const isBigInt: (ast: AST) => ast is BigInt; /** * Narrows an {@link AST} to {@link Symbol}. * * @category Guard * @since 4.0.0 */ export declare const isSymbol: (ast: AST) => ast is Symbol; /** * Narrows an {@link AST} to {@link Literal}. * * @category Guard * @since 4.0.0 */ export declare const isLiteral: (ast: AST) => ast is Literal; /** * Narrows an {@link AST} to {@link UniqueSymbol}. * * @category Guard * @since 4.0.0 */ export declare const isUniqueSymbol: (ast: AST) => ast is UniqueSymbol; /** * Narrows an {@link AST} to {@link ObjectKeyword}. * * @category Guard * @since 4.0.0 */ export declare const isObjectKeyword: (ast: AST) => ast is ObjectKeyword; /** * Narrows an {@link AST} to {@link Enum}. * * @category Guard * @since 4.0.0 */ export declare const isEnum: (ast: AST) => ast is Enum; /** * Narrows an {@link AST} to {@link TemplateLiteral}. * * @category Guard * @since 4.0.0 */ export declare const isTemplateLiteral: (ast: AST) => ast is TemplateLiteral; /** * Narrows an {@link AST} to {@link Arrays}. * * @category Guard * @since 4.0.0 */ export declare const isArrays: (ast: AST) => ast is Arrays; /** * Narrows an {@link AST} to {@link Objects}. * * @category Guard * @since 4.0.0 */ export declare const isObjects: (ast: AST) => ast is Objects; /** * Narrows an {@link AST} to {@link Union}. * * @category Guard * @since 4.0.0 */ export declare const isUnion: (ast: AST) => ast is Union; /** * Narrows an {@link AST} to {@link Suspend}. * * @category Guard * @since 4.0.0 */ export declare const isSuspend: (ast: AST) => ast is Suspend; /** * A single step in an {@link Encoding} chain, pairing a target {@link AST} * with a `Transformation` or `Middleware` that converts values between the * current node and the target. * * - `to` — the AST node on the other side of this transformation step. * - `transformation` — the bidirectional conversion logic (decode/encode). * * Links are composed into a non-empty array ({@link Encoding}) attached to * AST nodes that have a different encoded representation. * * @see {@link Encoding} * @see {@link decodeTo} * * @category model * @since 4.0.0 */ export declare class Link { readonly to: AST; readonly transformation: Transformation.Transformation | Transformation.Middleware; constructor(to: AST, transformation: Transformation.Transformation | Transformation.Middleware); } /** * A non-empty chain of {@link Link} values representing the transformation * steps between a schema's decoded (type) form and its encoded (wire) form. * * Stored on {@link Base.encoding}. When `undefined`, the node has no * encoding transformation (type and encoded forms are identical). * * @see {@link Link} * @see {@link toEncoded} * * @category model * @since 4.0.0 */ export type Encoding = readonly [Link, ...Array]; /** * Options that control parsing/validation behavior. * * Pass to `Schema.decodeUnknown`, `Schema.encode`, etc. to customize error * reporting, excess property handling, and output key ordering. * * - `errors` — `"first"` (default) stops at the first error; `"all"` * collects every error. * - `onExcessProperty` — `"ignore"` (default) strips unknown keys; * `"error"` fails; `"preserve"` keeps them. * - `propertyOrder` — `"none"` (default) lets the system choose key order; * `"original"` preserves input key order. * * @category model * @since 4.0.0 */ export interface ParseOptions { /** * The `errors` option allows you to receive all parsing errors when * attempting to parse a value using a schema. By default only the first error * is returned, but by setting the `errors` option to `"all"`, you can receive * all errors that occurred during the parsing process. This can be useful for * debugging or for providing more comprehensive error messages to the user. * * default: "first" */ readonly errors?: "first" | "all" | undefined; /** * When using a `Objects` to parse a value, by default any properties that * are not specified in the schema will be stripped out from the output. This * is because the `Objects` is expecting a specific shape for the parsed * value, and any excess properties do not conform to that shape. * * However, you can use the `onExcessProperty` option (default value: * `"ignore"`) to trigger a parsing error. This can be particularly useful in * cases where you need to detect and handle potential errors or unexpected * values. * * If you want to allow excess properties to remain, you can use * `onExcessProperty` set to `"preserve"`. * * default: "ignore" */ readonly onExcessProperty?: "ignore" | "error" | "preserve" | undefined; /** * The `propertyOrder` option provides control over the order of object fields * in the output. This feature is useful when the sequence of keys is * important for the consuming processes or when maintaining the input order * enhances readability and usability. * * By default, the `propertyOrder` option is set to `"none"`. This means that * the internal system decides the order of keys to optimize parsing speed. * The order of keys in this mode should not be considered stable, and it's * recommended not to rely on key ordering as it may change in future updates * without notice. * * Setting `propertyOrder` to `"original"` ensures that the keys are ordered * as they appear in the input during the decoding/encoding process. * * default: "none" */ readonly propertyOrder?: "none" | "original" | undefined; /** * Whether to disable checks while still applying defaults and * transformations. */ readonly disableChecks?: boolean | undefined; /** * The maximum number of async effects to run concurrently. * * Defaults to 1. */ readonly concurrency?: number | "unbounded" | undefined; } /** * Per-property metadata attached to AST nodes via {@link Base.context}. * * Tracks whether a property key is optional, mutable, has a constructor * default, or carries key-level annotations. Typically set by helpers like * {@link optionalKey} and `Schema.mutableKey`. * * - `isOptional` — the property key may be absent from the input. * - `isMutable` — the property is `readonly` when `false`. * - `defaultValue` — an {@link Encoding} applied during construction to * supply missing values. * - `annotations` — key-level annotations (e.g. description of the key * itself). * * @see {@link optionalKey} * @see {@link isOptional} * * @category model * @since 4.0.0 */ export declare class Context { readonly isOptional: boolean; readonly isMutable: boolean; /** Used for constructor default values (e.g. `withConstructorDefault` API) */ readonly defaultValue: Encoding | undefined; readonly annotations: Schema.Annotations.Key | undefined; constructor(isOptional: boolean, isMutable: boolean, /** Used for constructor default values (e.g. `withConstructorDefault` API) */ defaultValue?: Encoding | undefined, annotations?: Schema.Annotations.Key | undefined); } /** * Non-empty array of validation {@link Check} values attached to an AST node * via {@link Base.checks}. * * Checks are run after basic type matching succeeds. They represent * refinements like `minLength`, `pattern`, `int`, etc. * * @see {@link Check} * @see {@link Filter} * @see {@link FilterGroup} * * @category model * @since 4.0.0 */ export type Checks = readonly [Check, ...Array>]; declare const TypeId = "~effect/Schema"; /** * Abstract base class for all {@link AST} node variants. * * Every AST node extends `Base` and inherits these fields: * * - `annotations` — user-supplied metadata (identifier, title, description, * arbitrary keys). * - `checks` — optional {@link Checks} for post-type-match validation. * - `encoding` — optional {@link Encoding} chain for type ↔ wire * transformations. * - `context` — optional {@link Context} for per-property metadata. * * Subclasses add a `_tag` discriminant and variant-specific data. * * @see {@link AST} * * @category model * @since 4.0.0 */ export declare abstract class Base { readonly [TypeId] = "~effect/Schema"; abstract readonly _tag: string; readonly annotations: Schema.Annotations.Annotations | undefined; readonly checks: Checks | undefined; readonly encoding: Encoding | undefined; readonly context: Context | undefined; constructor(annotations?: Schema.Annotations.Annotations | undefined, checks?: Checks | undefined, encoding?: Encoding | undefined, context?: Context | undefined); toString(): string; } /** * AST node for user-defined opaque types with custom parsing logic. * * Use when none of the built-in AST nodes fit. The `run` function receives * `typeParameters` and returns a parser that validates/transforms raw input. * * - `typeParameters` — inner schemas this declaration is parameterized over * (e.g. the element type for a custom collection). * - `run` — factory producing the actual parse function. * * @see {@link isDeclaration} * * @category model * @since 4.0.0 */ export declare class Declaration extends Base { readonly _tag = "Declaration"; readonly typeParameters: ReadonlyArray; readonly run: (typeParameters: ReadonlyArray) => (input: unknown, self: Declaration, options: ParseOptions) => Effect.Effect; constructor(typeParameters: ReadonlyArray, run: (typeParameters: ReadonlyArray) => (input: unknown, self: Declaration, options: ParseOptions) => Effect.Effect, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * AST node matching the `null` literal value. * * Parsing succeeds only when the input is exactly `null`. * * @see {@link null} * @see {@link isNull} * * @category model * @since 4.0.0 */ export declare class Null extends Base { readonly _tag = "Null"; } declare const null_: Null; export { /** * Singleton {@link Null} AST instance. * * @since 4.0.0 */ null_ as null }; /** * AST node matching the `undefined` value. * * Parsing succeeds only when the input is exactly `undefined`. * * @see {@link undefined} * @see {@link isUndefined} * * @category model * @since 4.0.0 */ export declare class Undefined extends Base { readonly _tag = "Undefined"; } declare const undefined_: Undefined; export { /** * Singleton {@link Undefined} AST instance. * * @since 4.0.0 */ undefined_ as undefined }; /** * AST node matching the `void` type (accepts `undefined` at runtime). * * Behaves like {@link Undefined} for parsing but represents the TypeScript * `void` type semantically. * * @see {@link void} * @see {@link isVoid} * * @category model * @since 4.0.0 */ export declare class Void extends Base { readonly _tag = "Void"; } declare const void_: Void; export { /** * Singleton {@link Void} AST instance. * * @since 4.0.0 */ void_ as void }; /** * AST node representing the `never` type — no value matches. * * Parsing always fails. Useful as a placeholder in unions or as the result * of narrowing that eliminates all options. * * @see {@link never} * @see {@link isNever} * * @category model * @since 4.0.0 */ export declare class Never extends Base { readonly _tag = "Never"; } /** * Singleton {@link Never} AST instance. * * @since 4.0.0 */ export declare const never: Never; /** * AST node representing the `any` type — every value matches. * * @see {@link any} * @see {@link isAny} * * @category model * @since 4.0.0 */ export declare class Any extends Base { readonly _tag = "Any"; } /** * Singleton {@link Any} AST instance. * * @since 4.0.0 */ export declare const any: Any; /** * AST node representing the `unknown` type — every value matches. * * Unlike {@link Any}, this is type-safe: the parsed result is typed as * `unknown` rather than `any`. * * @see {@link unknown} * @see {@link isUnknown} * * @category model * @since 4.0.0 */ export declare class Unknown extends Base { readonly _tag = "Unknown"; } /** * Singleton {@link Unknown} AST instance. * * @since 4.0.0 */ export declare const unknown: Unknown; /** * AST node matching the TypeScript `object` type — accepts objects, arrays, * and functions (anything non-primitive and non-null). * * @see {@link objectKeyword} * @see {@link isObjectKeyword} * * @category model * @since 4.0.0 */ export declare class ObjectKeyword extends Base { readonly _tag = "ObjectKeyword"; } /** * Singleton {@link ObjectKeyword} AST instance. * * @since 4.0.0 */ export declare const objectKeyword: ObjectKeyword; /** * AST node representing a TypeScript `enum`. * * Holds `enums` as an array of `[name, value]` pairs where values are * `string | number`. Parsing succeeds when the input matches any enum value. * * @see {@link isEnum} * * @category model * @since 4.0.0 */ export declare class Enum extends Base { readonly _tag = "Enum"; readonly enums: ReadonlyArray; constructor(enums: ReadonlyArray, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * AST node representing a TypeScript template literal type * (e.g. `` `user_${string}` ``). * * `parts` is an array of AST nodes; each part contributes to the * template literal pattern. A regex is derived from the parts to validate * strings at runtime. * * @see {@link isTemplateLiteral} * * @category model * @since 4.0.0 */ export declare class TemplateLiteral extends Base { readonly _tag = "TemplateLiteral"; readonly parts: ReadonlyArray; constructor(parts: ReadonlyArray, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * AST node matching a specific `unique symbol` value. * * Parsing succeeds only when the input is reference-equal to the stored * `symbol`. * * @see {@link isUniqueSymbol} * * @category model * @since 4.0.0 */ export declare class UniqueSymbol extends Base { readonly _tag = "UniqueSymbol"; readonly symbol: symbol; constructor(symbol: symbol, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * The set of primitive types that can appear as a {@link Literal} value. * * @see {@link Literal} * * @category model * @since 4.0.0 */ export type LiteralValue = string | number | boolean | bigint; /** * AST node matching an exact primitive value (string, number, boolean, or * bigint). * * Parsing succeeds only when the input is strictly equal (`===`) to the * stored `literal`. Numeric literals must be finite — `Infinity`, `-Infinity`, * and `NaN` are rejected at construction time. * * **Example** (Creating a literal AST) * * ```ts * import { SchemaAST } from "effect" * * const ast = new SchemaAST.Literal("active") * console.log(ast.literal) // "active" * ``` * * @see {@link LiteralValue} * @see {@link isLiteral} * * @category model * @since 4.0.0 */ export declare class Literal extends Base { readonly _tag = "Literal"; readonly literal: LiteralValue; constructor(literal: LiteralValue, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * AST node matching any `string` value. * * @see {@link string} * @see {@link isString} * * @category model * @since 4.0.0 */ export declare class String extends Base { readonly _tag = "String"; } /** * Singleton {@link String} AST instance. * * @since 4.0.0 */ export declare const string: String; /** * AST node matching any `number` value (including `NaN`, `Infinity`, * `-Infinity`). * * Default JSON serialization: * - Finite numbers are serialized as JSON numbers. * - `Infinity`, `-Infinity`, and `NaN` are serialized as JSON strings. * * If the node has an `isFinite` or `isInt` check, the string fallback is * skipped since non-finite values cannot occur. * * @see {@link number} * @see {@link isNumber} * * @category model * @since 4.0.0 */ export declare class Number extends Base { readonly _tag = "Number"; } /** * Singleton {@link Number} AST instance. * * @since 4.0.0 */ export declare const number: Number; /** * AST node matching any `boolean` value (`true` or `false`). * * @see {@link boolean} * @see {@link isBoolean} * * @category model * @since 4.0.0 */ export declare class Boolean extends Base { readonly _tag = "Boolean"; } /** * Singleton {@link Boolean} AST instance. * * @since 4.0.0 */ export declare const boolean: Boolean; /** * AST node matching any `symbol` value. * * When serialized to a string-based codec, symbols are converted via * `Symbol.keyFor` and must be registered with `Symbol.for`. * * @see {@link symbol} * @see {@link isSymbol} * * @category model * @since 4.0.0 */ export declare class Symbol extends Base { readonly _tag = "Symbol"; } /** * Singleton {@link Symbol} AST instance. * * @since 4.0.0 */ export declare const symbol: Symbol; /** * AST node matching any `bigint` value. * * When serialized to a string-based codec, bigints are converted to/from * their decimal string representation. * * @see {@link bigInt} * @see {@link isBigInt} * * @category model * @since 4.0.0 */ export declare class BigInt extends Base { readonly _tag = "BigInt"; } /** * Singleton {@link BigInt} AST instance. * * @since 4.0.0 */ export declare const bigInt: BigInt; /** * AST node for array-like types — both tuples and arrays. * * - `elements` — positional element types (tuple elements). An element is * optional if its {@link Context.isOptional} is `true`. * - `rest` — the rest/variadic element types. When non-empty, the first * entry is the "spread" type (e.g. `...Array`), and subsequent * entries are trailing positional elements after the spread. * - `isMutable` — whether the resulting array is `readonly` (`false`) or * mutable (`true`). * * Construction enforces TypeScript ordering rules: a required element * cannot follow an optional one, and an optional element cannot follow a * rest element. * * **Example** (Inspecting a tuple AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.Tuple([Schema.String, Schema.Number]) * const ast = schema.ast * * if (SchemaAST.isArrays(ast)) { * console.log(ast.elements.length) // 2 * console.log(ast.rest.length) // 0 * } * ``` * * @see {@link isArrays} * @see {@link Objects} * * @category model * @since 4.0.0 */ export declare class Arrays extends Base { readonly _tag = "Arrays"; readonly isMutable: boolean; readonly elements: ReadonlyArray; readonly rest: ReadonlyArray; constructor(isMutable: boolean, elements: ReadonlyArray, rest: ReadonlyArray, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * A named property within an {@link Objects} node. * * Pairs a `name` (any `PropertyKey`) with a `type` ({@link AST}). The * property's optionality and mutability are determined by the `type`'s * {@link Context}. * * @see {@link Objects} * * @category model * @since 4.0.0 */ export declare class PropertySignature { readonly name: PropertyKey; readonly type: AST; constructor(name: PropertyKey, type: AST); } /** * Bidirectional merge strategy for index signature key-value pairs. * * Used by {@link IndexSignature} when the same key appears multiple times * (e.g. from `Schema.extend` or overlapping records). Provides separate * `decode` and `encode` combiners that determine how duplicate entries are * merged. * * @see {@link IndexSignature} * * @category model * @since 4.0.0 */ export declare class KeyValueCombiner { readonly decode: Combiner.Combiner | undefined; readonly encode: Combiner.Combiner | undefined; constructor(decode: Combiner.Combiner | undefined, encode: Combiner.Combiner | undefined); } /** * An index signature entry within an {@link Objects} node. * * - `parameter` — the key type AST (e.g. {@link String} for `string` keys, * {@link TemplateLiteral} for patterned keys). * - `type` — the value type AST. * - `merge` — optional {@link KeyValueCombiner} for handling duplicate keys. * * Using `Schema.optionalKey` on the value type is not allowed for index * signatures (throws at construction); use `Schema.optional` instead. * * @see {@link Objects} * @see {@link PropertySignature} * * @category model * @since 4.0.0 */ export declare class IndexSignature { readonly parameter: AST; readonly type: AST; readonly merge: KeyValueCombiner | undefined; constructor(parameter: AST, type: AST, merge: KeyValueCombiner | undefined); } /** * AST node for object-like types — both structs and records. * * - `propertySignatures` — named properties with their types (struct fields). * - `indexSignatures` — index signature entries (record patterns), each with * a `parameter` AST (the key type) and a `type` AST (the value type). * * An `Objects` with no properties and no index signatures acts as a bare * `object | array` type check (accepts any non-nullish value). * * Duplicate property names throw at construction time. * * **Example** (Inspecting a struct AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.Struct({ name: Schema.String }) * const ast = schema.ast * * if (SchemaAST.isObjects(ast)) { * for (const ps of ast.propertySignatures) { * console.log(ps.name, ps.type._tag) * } * // "name" "String" * } * ``` * * @see {@link isObjects} * @see {@link PropertySignature} * @see {@link IndexSignature} * @see {@link Arrays} * * @category model * @since 4.0.0 */ export declare class Objects extends Base { readonly _tag = "Objects"; readonly propertySignatures: ReadonlyArray; readonly indexSignatures: ReadonlyArray; constructor(propertySignatures: ReadonlyArray, indexSignatures: ReadonlyArray, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); private rebuild; } /** * AST node representing a union of schemas. * * - `types` — the member AST nodes. * - `mode` — `"anyOf"` succeeds on the first match (like TypeScript unions); * `"oneOf"` requires exactly one member to match (fails if multiple do). * * During parsing, members are tried in order. An internal candidate index * narrows which members to try based on the runtime type of the input and * discriminant ("sentinel") fields, making large unions efficient. * * **Example** (Inspecting a union AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.Union([Schema.String, Schema.Number]) * const ast = schema.ast * * if (SchemaAST.isUnion(ast)) { * console.log(ast.types.length) // 2 * console.log(ast.mode) // "anyOf" * } * ``` * * @see {@link isUnion} * * @category model * @since 4.0.0 */ export declare class Union extends Base { readonly _tag = "Union"; readonly types: ReadonlyArray; readonly mode: "anyOf" | "oneOf"; constructor(types: ReadonlyArray, mode: "anyOf" | "oneOf", annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * AST node for lazy/recursive schemas. * * Wraps a thunk (`() => AST`) that is memoized on first call. Use this to * define recursive or mutually recursive schemas without infinite loops at * construction time. * * **Example** (Recursive schema AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * interface Category { * readonly name: string * readonly children: ReadonlyArray * } * * const Category = Schema.Struct({ * name: Schema.String, * children: Schema.Array(Schema.suspend((): Schema.Codec => Category)) * }) * * // The recursive branch is a Suspend node * ``` * * @see {@link isSuspend} * * @category model * @since 4.0.0 */ export declare class Suspend extends Base { readonly _tag = "Suspend"; readonly thunk: () => AST; constructor(thunk: () => AST, annotations?: Schema.Annotations.Annotations, checks?: Checks, encoding?: Encoding, context?: Context); } /** * A single validation check attached to an AST node. * * - `run` — the validation function. Returns `undefined` on success, or an * `Issue` on failure. * - `annotations` — optional filter-level metadata (expected message, meta * tags, arbitrary constraint hints). * - `aborted` — when `true`, parsing stops immediately after this filter * fails (no further checks run). * * Use `.annotate()` to add metadata and `.abort()` to mark as aborting. * Combine with another check via `.and()` to form a {@link FilterGroup}. * * @see {@link FilterGroup} * @see {@link Check} * @see {@link isPattern} * * @category model * @since 4.0.0 */ export declare class Filter extends Pipeable.Class { readonly _tag = "Filter"; readonly run: (input: E, self: AST, options: ParseOptions) => Issue.Issue | undefined; readonly annotations: Schema.Annotations.Filter | undefined; /** * Whether the parsing process should be aborted after this check has failed. */ readonly aborted: boolean; constructor(run: (input: E, self: AST, options: ParseOptions) => Issue.Issue | undefined, annotations?: Schema.Annotations.Filter | undefined, /** * Whether the parsing process should be aborted after this check has failed. */ aborted?: boolean); annotate(annotations: Schema.Annotations.Filter): Filter; abort(): Filter; and(other: Check, annotations?: Schema.Annotations.Filter): FilterGroup; } /** * A composite validation check grouping multiple {@link Check} values. * * Created by calling `.and()` on a {@link Filter} or another `FilterGroup`. * All inner checks are run; failures from aborted filters still stop * evaluation. * * @see {@link Filter} * @see {@link Check} * * @category model * @since 4.0.0 */ export declare class FilterGroup extends Pipeable.Class { readonly _tag = "FilterGroup"; readonly checks: readonly [Check, ...Array>]; readonly annotations: Schema.Annotations.Filter | undefined; constructor(checks: readonly [Check, ...Array>], annotations?: Schema.Annotations.Filter | undefined); annotate(annotations: Schema.Annotations.Filter): FilterGroup; and(other: Check, annotations?: Schema.Annotations.Filter): FilterGroup; } /** * A validation check — either a single {@link Filter} or a composite * {@link FilterGroup}. * * Stored in the {@link Checks} array on {@link Base.checks}. * * @see {@link Filter} * @see {@link FilterGroup} * * @category model * @since 4.0.0 */ export type Check = Filter | FilterGroup; /** * Creates a {@link Filter} that validates strings against a regular expression. * * - Returns a `Filter` suitable for use with `Schema.filter` or * attached directly to a `String` AST node via checks. * - The regex `source` is stored in annotations for serialization and * arbitrary generation. * * **Example** (Validating an email pattern) * * ```ts * import { SchemaAST } from "effect" * * const emailFilter = SchemaAST.isPattern(/^[^@]+@[^@]+$/) * ``` * * @see {@link Filter} * * @since 4.0.0 */ export declare function isPattern(regExp: globalThis.RegExp, annotations?: Schema.Annotations.Filter): Filter; export declare function mapOrSame(as: ReadonlyArray, f: (a: A) => A): ReadonlyArray; /** * Marks an AST node's property key as optional by setting * {@link Context.isOptional} to `true`. * * Also propagates the optional flag through the last link of the encoding * chain if present. * * @see {@link isOptional} * @see {@link Context} * * @since 4.0.0 */ export declare function optionalKey(ast: A): A; /** * Attaches a `Transformation` to the `to` AST, making it decode from the * `from` AST and encode back to it. * * This is the low-level primitive behind `Schema.transform` and * `Schema.transformOrFail`. It appends a {@link Link} to the `to` node's * encoding chain. * * - Does not mutate either input. * - Returns a new AST with the same type as `to`. * * @see {@link Link} * @see {@link Encoding} * @see {@link flip} * * @since 4.0.0 */ export declare function decodeTo(from: AST, to: A, transformation: Transformation.Transformation): A; /** * Returns `true` if the AST node represents an optional property. * * Checks `ast.context?.isOptional`. Defaults to `false` when no * {@link Context} is set. * * @see {@link optionalKey} * @see {@link Context} * * @since 4.0.0 */ export declare function isOptional(ast: AST): boolean; /** * Strips all encoding transformations from an AST, returning the decoded * (type-level) representation. * * - Memoized: same input reference → same output reference. * - Recursively walks into composite nodes ({@link Arrays}, {@link Objects}, * {@link Union}, {@link Suspend}). * - Does not mutate the input. * * **Example** (Getting the type AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.NumberFromString * const typeAst = SchemaAST.toType(schema.ast) * console.log(typeAst._tag) // "Number" * ``` * * @see {@link toEncoded} * @see {@link flip} * * @since 4.0.0 */ export declare const toType: (ast: A) => A; /** * Returns the encoded (wire-format) AST by flipping and then stripping * encodings. * * Equivalent to `toType(flip(ast))`. This gives you the AST that describes * the shape of the serialized/encoded data. * * - Memoized: same input reference → same output reference. * - Does not mutate the input. * * **Example** (Getting the encoded AST) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.NumberFromString * const encodedAst = SchemaAST.toEncoded(schema.ast) * console.log(encodedAst._tag) // "String" * ``` * * @see {@link toType} * @see {@link flip} * * @since 4.0.0 */ export declare const toEncoded: (ast: AST) => AST; /** * Swaps the decode and encode directions of an AST's {@link Encoding} chain. * * After flipping, what was decoding becomes encoding and vice versa. This is * the core operation behind `Schema.encode` — encoding a value is decoding * with a flipped AST. * * - Memoized: same input reference → same output reference. * - Recursively walks composite nodes. * - Does not mutate the input. * * @see {@link toType} * @see {@link toEncoded} * * @since 4.0.0 */ export declare const flip: (ast: AST) => AST; /** * Returns all annotations from the AST node. * * If the node has {@link Checks}, returns annotations from the last check * (which is where user-supplied annotations end up after `.pipe(Schema.annotations(...))`). * Otherwise returns `Base.annotations` directly. * * **Example** (Reading annotations) * * ```ts * import { Schema, SchemaAST } from "effect" * * const schema = Schema.String.annotate({ title: "Name" }) * const annotations = SchemaAST.resolve(schema.ast) * console.log(annotations?.title) // "Name" * ``` * * @see {@link resolveAt} * @see {@link resolveIdentifier} * @see {@link resolveTitle} * @see {@link resolveDescription} * * @since 4.0.0 */ export declare const resolve: (ast: AST) => Schema.Annotations.Annotations | undefined; /** * Returns a single annotation value by key from the AST node. * * Like {@link resolve}, reads from the last check's annotations when checks * are present. Returns `undefined` if the key is not found. * * @see {@link resolve} * * @since 4.0.0 */ export declare const resolveAt: (key: string) => (ast: AST) => A | undefined; /** * Returns the `identifier` annotation from the AST node, if set. * * The identifier is typically set by `Schema.annotations({ identifier: "..." })` * and is used for error messages and schema identification. * * @see {@link resolve} * @see {@link resolveTitle} * * @since 4.0.0 */ export declare const resolveIdentifier: (ast: AST) => string | undefined; /** * Returns the `title` annotation from the AST node, if set. * * @see {@link resolve} * @see {@link resolveIdentifier} * @see {@link resolveDescription} * * @since 4.0.0 */ export declare const resolveTitle: (ast: AST) => string | undefined; /** * Returns the `description` annotation from the AST node, if set. * * @see {@link resolve} * @see {@link resolveTitle} * @see {@link resolveIdentifier} * * @since 4.0.0 */ export declare const resolveDescription: (ast: AST) => string | undefined; //# sourceMappingURL=SchemaAST.d.ts.map