import type { Expression, Tag, TypeAliasEntry, VariableType } from "../types.js";
/**
 * Bindings map: value-parameter name → use-site Expression that should
 * replace any `variableName` reference to that param inside the alias's
 * tag-argument expressions.
 *
 * Example: for `Age(18)` instantiating `type Age(min: number) = number`
 * the bindings are `{ min: <numberLiteral 18> }`.
 */
export type ValueArgBindings = Record<string, Expression>;
/**
 * True when `vt` is a reference to a value-parameterized alias —
 * either with explicit use-site value args (`Foo(18)`) or as a bare
 * reference (`Foo`) on an alias whose value params all have defaults.
 *
 * This is the single canonical predicate for "this reference needs
 * inline-at-use-site emission and `applyValueArgs` substitution". The
 * three codegen branches that diverge from the bare-alias path
 * (`typeToZodSchema`, `validationDescriptor`, `hasAnyValidateTag`)
 * should all use this — keeping the divergence rule expressed in
 * exactly one place.
 *
 * Why bare refs count too: a value-parameterized alias never emits a
 * top-level schema const (there's no single schema without args), so
 * even bare uses must be inlined. `applyValueArgs` handles the
 * missing-args case by filling defaults or throwing a clear error if a
 * required (defaultless) param was omitted.
 */
export declare function isValueParamInstantiation(vt: VariableType, entry: TypeAliasEntry | undefined): boolean;
/**
 * Walk a `Tag` (specifically its `arguments` list) and return a fresh
 * Tag whose arguments have every value-parameter `variableName`
 * reference replaced with a structural CLONE of the bound expression.
 *
 * The input tag is not mutated. The returned tag shares no Expression
 * nodes with the input, so callers may further substitute or attach
 * additional tags without aliasing.
 */
export declare function substituteValueArgsInTag(tag: Tag, bindings: ValueArgBindings): Tag;
/**
 * Recursively walk an Expression tree, replacing any `variableName`
 * whose `value` matches a key in `bindings` with a structural CLONE
 * of the bound expression. All other nodes are returned unchanged
 * (deep-cloned only along the spine that contains a substitution
 * target — leaves not in `bindings` reuse the original node, but the
 * containing array/object is rebuilt so the caller sees a fresh tree
 * along the substitution path).
 *
 * For nodes outside the restricted tag-arg subset this is a no-op
 * passthrough: only literals, identifiers, object literals (with
 * splats), valueAccess chains, and function-call arg lists inside
 * PFAs are descended into. Anything else (binops, ternaries, etc.)
 * is returned unchanged because the tag-arg parser would have
 * rejected it before substitution is ever reached.
 */
export declare function substituteValueArgsInExpression(expr: Expression, bindings: ValueArgBindings): Expression;
/**
 * Take a `TypeAliasEntry` and the use-site `valueArgs` list, and
 * return a fresh `TypeAliasEntry` whose `tags` have every value-param
 * identifier reference replaced with the corresponding argument
 * expression.
 *
 * Behavior:
 *
 * 1. Validates arity: too many args is an error; missing args are
 *    filled from `valueParams[i].default` when present, or reported.
 * 2. Builds the bindings map (param name → arg expression).
 * 3. Maps `entry.tags` through `substituteValueArgsInTag`.
 * 4. Returns a new entry with the substituted tags. `body` and
 *    `typeParams` are kept as-is — type-param substitution is handled
 *    by the existing `substituteTypeParams` pass, which runs BEFORE
 *    `applyValueArgs` when both are needed (see assignability.ts).
 *
 * Throws a `TypeError` for arg-count / arg-type problems. The message
 * is intentionally readable so it bubbles directly to the user.
 *
 * The `aliasName` parameter is used only for error messages.
 */
export declare function applyValueArgs(entry: TypeAliasEntry, valueArgs: Expression[] | undefined, aliasName: string): TypeAliasEntry;
/**
 * Walk a `VariableType` tree and substitute value-arg bindings into any
 * inner `typeAliasVariable` or `genericType` reference that itself
 * carries `valueArgs`. This enables wrapping aliases such as
 * `type EvenInRange(low, high) = NumberInRange(low, high)` — when the
 * outer alias is resolved the inner reference's `valueArgs` need their
 * value-param identifier references replaced with the outer alias's
 * bound arguments.
 *
 * Returns a fresh tree along any spine touched by substitution; nodes
 * with no inner valueArgs pass through unchanged.
 */
export declare function substituteValueArgsInType(vt: VariableType, bindings: ValueArgBindings): VariableType;
