/** * A `StructFailure` represents a single specific failure in validation. */ type Failure = { value: any; key: any; type: string; refinement: string | undefined; message: string; branch: Array; path: Array; }; /** * `StructError` objects are thrown (or returned) when validation fails. * * Validation logic is design to exit early for maximum performance. The error * represents the first error encountered during validation. For more detail, * the `error.failures` property is a generator function that can be run to * continue validation and receive all the failures in the data. */ declare class StructError extends TypeError { value: any; key: any; type: string; refinement: string | undefined; path: Array; branch: Array; failures: () => Array; [x: string]: any; constructor(failure: Failure, failures: () => Generator); } /** * Assign properties from one type to another, overwriting existing. */ type Assign = Simplify>; /** * A schema for enum structs. */ type EnumSchema = { [K in T]: K; }; /** * Check if a type is an exact match. */ type IsMatch = T extends G ? (G extends T ? T : never) : never; /** * Check if a type is a record type. */ type IsRecord = T extends object ? string extends keyof T ? T : never : never; /** * Check if a type is a tuple. */ type IsTuple = T extends [ any ] ? T : T extends [ any, any ] ? T : T extends [ any, any, any ] ? T : T extends [ any, any, any, any ] ? T : T extends [ any, any, any, any, any ] ? T : never; /** * Check if a type is a union. */ type IsUnion = (T extends any ? (U extends T ? false : true) : false) extends false ? never : T; /** * A schema for object structs. */ type ObjectSchema = Record>; /** * Infer a type from an object struct schema. */ type ObjectType = Simplify; }>>; /** * Omit properties from a type that extend from a specific type. */ type OmitBy = Omit ? K : never; }[keyof T]>; /** * Normalize properties of a type that allow `undefined` to make them optional. */ type Optionalize = OmitBy & Partial>; /** * Transform an object schema type to represent a partial. */ type PartialObjectSchema = { [K in keyof S]: Struct | undefined>; }; /** * Pick properties from a type that extend from a specific type. */ type PickBy = Pick ? K : never; }[keyof T]>; /** * Simplifies a type definition to its most basic representation. */ type Simplify = T extends any[] | Date ? T : { [K in keyof T]: T[K]; } & {}; /** * A schema for any type of struct. */ type StructSchema = [ T ] extends [ string ] ? [ T ] extends [ IsMatch ] ? null : [ T ] extends [ IsUnion ] ? EnumSchema : T : [ T ] extends [ number ] ? [ T ] extends [ IsMatch ] ? null : [ T ] extends [ IsUnion ] ? EnumSchema : T : [ T ] extends [ boolean ] ? [ T ] extends [ IsMatch ] ? null : T : T extends bigint | symbol | undefined | null | Function | Date | Error | RegExp | Map | WeakMap | Set | WeakSet | Promise ? null : T extends Array ? T extends IsTuple ? null : Struct : T extends object ? T extends IsRecord ? null : { [K in keyof T]: Describe; } : null; /** * A schema for tuple structs. */ type TupleSchema = { [K in keyof T]: Struct; }; /** * `Struct` objects encapsulate the validation logic for a specific type of * values. Once constructed, you use the `assert`, `is` or `validate` helpers to * validate unknown input data against the struct. */ declare class Struct { readonly TYPE: T; type: string; schema: S; coercer: (value: unknown, context: Context) => unknown; validator: (value: unknown, context: Context) => Iterable; refiner: (value: T, context: Context) => Iterable; entries: (value: unknown, context: Context) => Iterable<[ string | number, unknown, Struct | Struct ]>; constructor(props: { type: string; schema: S; coercer?: Coercer; validator?: Validator; refiner?: Refiner; entries?: Struct["entries"]; }); /** * Assert that a value passes the struct's validation, throwing if it doesn't. */ assert(value: unknown): asserts value is T; /** * Create a value with the struct's coercion logic, then validate it. */ create(value: unknown): T; /** * Check if a value passes the struct's validation. */ is(value: unknown): value is T; /** * Mask a value, coercing and validating it, but returning only the subset of * properties defined by the struct's schema. */ mask(value: unknown): T; /** * Validate a value with the struct's validation logic, returning a tuple * representing the result. * * You may optionally pass `true` for the `withCoercion` argument to coerce * the value before attempting to validate it. If you do, the result will * contain the coerced result when successful. */ validate(value: unknown, options?: { coerce?: boolean; }): [ StructError, undefined ] | [ undefined, T ]; } /** * Assert that a value passes a struct, throwing if it doesn't. */ declare function assert(value: unknown, struct: Struct): asserts value is T; /** * Create a value with the coercion logic of struct and validate it. */ declare function create(value: unknown, struct: Struct): T; /** * Mask a value, returning only the subset of properties defined by a struct. */ declare function mask(value: unknown, struct: Struct): T; /** * Check if a value passes a struct. */ declare function is(value: unknown, struct: Struct): value is T; /** * Validate a value against a struct, returning an error if invalid, or the * value (with potential coercion) if valid. */ declare function validate(value: unknown, struct: Struct, options?: { coerce?: boolean; mask?: boolean; }): [ StructError, undefined ] | [ undefined, T ]; /** * A `Context` contains information about the current location of the * validation inside the initial input value. */ type Context = { branch: Array; path: Array; }; /** * A type utility to extract the type from a `Struct` class. */ type Infer> = T["TYPE"]; /** * A type utility to describe that a struct represents a TypeScript type. */ type Describe = Struct>; /** * A `Result` is returned from validation functions. */ type Result = boolean | string | Partial | Iterable>; /** * A `Coercer` takes an unknown value and optionally coerces it. */ type Coercer = (value: T, context: Context) => unknown; /** * A `Validator` takes an unknown value and validates it. */ type Validator = (value: unknown, context: Context) => Result; /** * A `Refiner` takes a value of a known type and validates it against a further * constraint. */ type Refiner = (value: T, context: Context) => Result; /** * Augment a `Struct` to add an additional coercion step to its input. * * This allows you to transform input data before validating it, to increase the * likelihood that it passes validation—for example for default values, parsing * different formats, etc. * * Note: You must use `create(value, Struct)` on the value to have the coercion * take effect! Using simply `assert()` or `is()` will not use coercion. */ declare function coerce(struct: Struct, condition: Struct, coercer: Coercer): Struct; /** * Augment a struct to replace `undefined` values with a default. * * Note: You must use `create(value, Struct)` on the value to have the coercion * take effect! Using simply `assert()` or `is()` will not use coercion. */ declare function defaulted(struct: Struct, fallback: any, options?: { strict?: boolean; }): Struct; /** * Augment a struct to trim string inputs. * * Note: You must use `create(value, Struct)` on the value to have the coercion * take effect! Using simply `assert()` or `is()` will not use coercion. */ declare function trimmed(struct: Struct): Struct; /** * Ensure that a string, array, map, or set is empty. */ declare function empty | Set, S extends any>(struct: Struct): Struct; /** * Ensure that a number or date is below a threshold. */ declare function max(struct: Struct, threshold: T, options?: { exclusive?: boolean; }): Struct; /** * Ensure that a number or date is above a threshold. */ declare function min(struct: Struct, threshold: T, options?: { exclusive?: boolean; }): Struct; /** * Ensure that a string matches a regular expression. */ declare function pattern(struct: Struct, regexp: RegExp): Struct; /** * Ensure that a string, array, number, date, map, or set has a size (or length, or time) between `min` and `max`. */ declare function size | Set, S extends any>(struct: Struct, min: number, max?: number): Struct; /** * Augment a `Struct` to add an additional refinement to the validation. * * The refiner function is guaranteed to receive a value of the struct's type, * because the struct's existing validation will already have passed. This * allows you to layer additional validation on top of existing structs. */ declare function refine(struct: Struct, name: string, refiner: Refiner): Struct; /** * Ensure that any value passes validation. */ declare function any(): Struct; /** * Ensure that a value is an array and that its elements are of a specific type. * * Note: If you omit the element struct, the arrays elements will not be * iterated at all. This can be helpful for cases where performance is critical, * and it is preferred to using `array(any())`. */ declare function array>(Element: T): Struct[], T>; declare function array(): Struct; /** * Ensure that a value is a boolean. */ declare function boolean(): Struct; /** * Ensure that a value is a valid `Date`. * * Note: this also ensures that the value is *not* an invalid `Date` object, * which can occur when parsing a date fails but still returns a `Date`. */ declare function date(): Struct; /** * Ensure that a value is one of a set of potential values. * * Note: after creating the struct, you can access the definition of the * potential values as `struct.schema`. */ declare function enums(values: readonly T[]): Struct; declare function enums(values: readonly T[]): Struct; /** * Ensure that a value is a function. */ declare function func(): Struct; /** * Ensure that a value is an instance of a specific class. */ declare function instance(Class: T): Struct, null>; /** * Ensure that a value is an integer. */ declare function integer(): Struct; /** * Ensure that a value matches all of a set of types. */ declare function intersection(Structs: TupleSchema<[ A ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P ]>): Struct; declare function intersection(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q ]>): Struct; /** * Ensure that a value is an exact value, using `===` for comparison. */ declare function literal(constant: T): Struct; declare function literal(constant: T): Struct; declare function literal(constant: T): Struct; declare function literal(constant: T): Struct; /** * Ensure that a value is a `Map` object, and that its keys and values are of * specific types. */ declare function map(): Struct, null>; declare function map(Key: Struct, Value: Struct): Struct, null>; /** * Ensure that no value ever passes validation. */ declare function never(): Struct; /** * Augment an existing struct to allow `null` values. */ declare function nullable(struct: Struct): Struct; /** * Ensure that a value is a number. */ declare function number(): Struct; /** * Ensure that a value is an object, that is has a known set of properties, * and that its properties are of specific types. * * Note: Unrecognized properties will fail validation. */ declare function object(): Struct, null>; declare function object(schema: S): Struct, S>; /** * Augment a struct to allow `undefined` values. */ declare function optional(struct: Struct): Struct; /** * Ensure that a value is an object with keys and values of specific types, but * without ensuring any specific shape of properties. * * Like TypeScript's `Record` utility. */ declare function record(Key: Struct, Value: Struct): Struct, null>; /** * Ensure that a value is a `RegExp`. * * Note: this does not test the value against the regular expression! For that * you need to use the `pattern()` refinement. */ declare function regexp(): Struct; /** * Ensure that a value is a `Set` object, and that its elements are of a * specific type. */ declare function set(): Struct, null>; declare function set(Element: Struct): Struct, null>; /** * Ensure that a value is a string. */ declare function string(): Struct; /** * Ensure that a value is a tuple of a specific length, and that each of its * elements is of a specific type. */ declare function tuple(Structs: TupleSchema<[ A ]>): Struct<[ A ], null>; declare function tuple(Structs: TupleSchema<[ A, B ]>): Struct<[ A, B ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C ]>): Struct<[ A, B, C ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D ]>): Struct<[ A, B, C, D ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E ]>): Struct<[ A, B, C, D, E ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F ]>): Struct<[ A, B, C, D, E, F ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G ]>): Struct<[ A, B, C, D, E, F, G ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H ]>): Struct<[ A, B, C, D, E, F, G, H ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I ]>): Struct<[ A, B, C, D, E, F, G, H, I ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J ]>): Struct<[ A, B, C, D, E, F, G, H, I, J ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L, M ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P ], null>; declare function tuple(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q ]>): Struct<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q ], null>; /** * Ensure that a value has a set of known properties of specific types. * * Note: Unrecognized properties are allowed and untouched. This is similar to * how TypeScript's structural typing works. */ declare function type(schema: S): Struct, S>; /** * Ensure that a value matches one of a set of types. */ declare function union(Structs: TupleSchema<[ A ]>): Struct; declare function union(Structs: TupleSchema<[ A, B ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P ]>): Struct; declare function union(Structs: TupleSchema<[ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q ]>): Struct; /** * Ensure that any value passes validation, without widening its type to `any`. */ declare function unknown(): Struct; /** * Create a new struct that combines the properties properties from multiple * object structs. * * Like JavaScript's `Object.assign` utility. */ declare function assign(A: Struct, A>, B: Struct, B>): Struct>, Assign>; declare function assign(A: Struct, A>, B: Struct, B>, C: Struct, C>): Struct, C>>, Assign, C>>; declare function assign(A: Struct, A>, B: Struct, B>, C: Struct, C>, D: Struct, D>): Struct, C>, D>>, Assign, C>, D>>; declare function assign(A: Struct, A>, B: Struct, B>, C: Struct, C>, D: Struct, D>, E: Struct, E>): Struct, C>, D>, E>>, Assign, C>, D>, E>>; /** * Define a new struct type with a custom validation function. */ declare function define(name: string, validator: Validator): Struct; /** * Create a new struct based on an existing struct, but the value is allowed to * be `undefined`. `log` will be called if the value is not `undefined`. */ declare function deprecated(struct: Struct, log: (value: unknown, ctx: Context) => void): Struct; /** * Create a struct with dynamic validation logic. * * The callback will receive the value currently being validated, and must * return a struct object to validate it with. This can be useful to model * validation logic that changes based on its input. */ declare function dynamic(fn: (value: unknown, ctx: Context) => Struct): Struct; /** * Create a struct with lazily evaluated validation logic. * * The first time validation is run with the struct, the callback will be called * and must return a struct object to use. This is useful for cases where you * want to have self-referential structs for nested data structures to avoid a * circular definition problem. */ declare function lazy(fn: () => Struct): Struct; /** * Create a new struct based on an existing object struct, but excluding * specific properties. * * Like TypeScript's `Omit` utility. */ declare function omit(struct: Struct, S>, keys: K[]): Struct>, Omit>; /** * Create a new struct based on an existing object struct, but with all of its * properties allowed to be `undefined`. * * Like TypeScript's `Partial` utility. */ declare function partial(struct: Struct, S> | S): Struct>, PartialObjectSchema>; /** * Create a new struct based on an existing object struct, but only including * specific properties. * * Like TypeScript's `Pick` utility. */ declare function pick(struct: Struct, S>, keys: K[]): Struct>, Pick>; /** * Define a new struct type with a custom validation function. * * @deprecated This function has been renamed to `define`. */ declare function struct(name: string, validator: Validator): Struct; export { Failure, StructError, Struct, assert, create, mask, is, validate, Context, Infer, Describe, Result, Coercer, Validator, Refiner, coerce, defaulted, trimmed, empty, max, min, pattern, size, refine, any, array, boolean, date, enums, func, instance, integer, intersection, literal, map, never, nullable, number, object, optional, record, regexp, set, string, tuple, type, union, unknown, assign, define, deprecated, dynamic, lazy, omit, partial, pick, struct };