import type { NaiveFabricator } from "../Fabricator/Types";
import type { Buildable, Produced, Produces } from "../Types";
import type { Fabricated } from "./Types";
/**
* The `this`-parameter constraint every kind's `.satisfies<$Target>()`
* intersects onto the receiver, so a mismatch names both sides on the call that
* failed — including a nested `T.object({ product: inner.satisfies
() })`,
* where the error lands on `inner` rather than the outer object.
*
* `$Produced` is each kind's own `Fabricated<…>` (or `Resolved<…>` for `derive`
* / `object.compute`, which have no `Fabricated` alias). A shared schema-level
* `Fabricated` form errors in the same place but reports `"schema
* produces": any`, which is why each kind still names its own produced type.
* The check is wrapped in a 1-tuple so it does not distribute over unions: a
* bare `$Produced extends $Target ? unknown : Error` on `"x" | null` becomes
* `unknown | Error`, which is `unknown`, and
* `T.nullable(…).satisfies()` would pass. Other signatures that were
* considered, and why they are not this:
*
* - A rest tuple `...check: D extends T ? [] : [error]` errors in the right place
* but says "Expected 1 arguments, but got 0".
* - A return type `D extends T ? this : Error` is silent when the result is
* unused, which is the typical `schema.satisfies()` statement.
*
* The target is not carried forward: the method is typed as returning the
* kind's `Schema`, not a type that remembers `$Target`, so a later `.extend`
* that changes a field's type is not re-checked. Put `.satisfies` last to check
* the final shape. Carrying `$Target` on every `Schema` interface would add a
* type parameter to all 25 kinds, and `.as`'s contravariant parameter check is
* where a variance shift on those interfaces surfaces — `Types.ts`'s
* `Fabricated` note records that same check breaking from a constraint on
* `$Schema`. The return is `Schema`, not polymorphic `this`, because
* `T.date.past` / `T.number.integer` / `T.symbol` are `Schema & { whereby, … }`
* and a `this` return is not assignable into those extra members — same as
* `.as()`.
*/
export type SatisfiesThis<$Produced, $Target> = [$Produced] extends [$Target] ? unknown : {
"schema produces": $Produced;
"but target requires": $Target;
};
/**
* Shared `.satisfies()` body — identity at runtime. A regular function so
* `this` is the schema it was called on; an arrow would capture the module
* scope. Distinct from the standalone {@link satisfies} because the two
* signatures cannot share a name: this one is a method (`this`, return the
* receiver); that one is a statement (`buildable`, `void`).
*/
export declare function schemaSatisfies<$Receiver>(this: $Receiver): $Receiver;
/**
* Whether `$Buildable` (a Schema or a built Fabricator) fabricates a value
* assignable to `$Target`. Resolves to `true` or to an object naming both
* sides, so asserting it (`true satisfies SatisfiedBy<…>`, or a local `type
* Expect<_ extends true> = true` as the test suites use) fails with a readable
* message rather than a bare `false`.
*
* Target first, so it reads as the sentence it asserts: `SatisfiedBy` — `Product` is satisfied by the schema. Swapping the
* parameters would name the opposite relationship.
*
* Assignable-to, not exact equality: extra fields pass. `T.optional` does not
* satisfy `note?: string` under `exactOptionalPropertyTypes` — it produces
* `note?: string | undefined` (present, present-as-`undefined`, or omitted).
* `T.omittable` produces `note?: string` and does.
*/
export type SatisfiedBy<$Target, $Buildable> = Fabricated<$Buildable> extends $Target ? true : {
produces: Fabricated<$Buildable>;
required: $Target;
};
/**
* Assert that `buildable` fabricates a value assignable to `$Target`. A
* statement, and a no-op at runtime — for a built Fabricator (which has no
* schema methods) and for a Schema the caller does not want to edit.
*
* `fabricate?: never` on the Schema arm is required. A built Fabricator has no
* `[Produces]`, and a type that lacks an optional property still matches `{
* readonly [Produces]?: Produced<$Target> }` — the same trap `Types.ts`'s
* `Fabricated` documents at `Types.ts`. Without the exclusion, a non-conforming
* Fabricator would pass the Schema arm unchecked. Ordered overloads do not
* replace this: overload resolution falls through a failing overload onto the
* next one, so a Fabricator rejected by `NaiveFabricator<$Target>` would still
* be accepted by the Schema arm.
*
* The Schema arm matches through the box (`Produced<$Target>`, `../Types.ts`),
* never `[Produces]?: $Target`: a caller compiling without
* `exactOptionalPropertyTypes` reads that optional slot as `$Target |
* undefined`, so a schema that may produce `undefined` would pass a target that
* excludes it.
*/
export declare function satisfies<$Target>(buildable: NaiveFabricator<$Target> | (Buildable & {
fabricate?: never;
readonly [Produces]?: Produced<$Target>;
})): void;