superstruct
Version:
A simple and composable way to validate data in JavaScript (and TypeScript).
1,236 lines (1,235 loc) • 28.8 kB
TypeScript
/**
* A `StructFailure` represents a single specific failure in validation.
*/
type Failure = {
value: any;
key: any;
type: string;
refinement: string | undefined;
message: string;
branch: Array<any>;
path: Array<any>;
};
/**
* `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<any>;
branch: Array<any>;
failures: () => Array<Failure>;
[x: string]: any;
constructor(failure: Failure, failures: () => Generator<Failure>);
}
/**
* Check if a type is a tuple.
*/
type IsTuple<T> = 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 record type.
*/
type IsRecord<T> = T extends object ? string extends keyof T ? T : never : never;
/**
* Check if a type is a generic string type.
*/
type IsGenericString<T> = T extends string ? string extends T ? T : never : never;
/**
* Normalize properties of a type that allow `undefined` to make them optional.
*/
type Optionalize<S extends object> = OmitBy<S, undefined> & Partial<PickBy<S, undefined>>;
/**
* Omit properties from a type that extend from a specific type.
*/
type OmitBy<T, V> = Omit<T, {
[K in keyof T]: V extends Extract<T[K], V> ? K : never;
}[keyof T]>;
/**
* Pick properties from a type that extend from a specific type.
*/
type PickBy<T, V> = Pick<T, {
[K in keyof T]: V extends Extract<T[K], V> ? K : never;
}[keyof T]>;
/**
* Simplifies a type definition to its most basic representation.
*/
type Simplify<T> = T extends any[] | Date ? T : {
[K in keyof T]: T[K];
} & {};
/**
* Assign properties from one type to another, overwriting existing.
*/
type Assign<T, U> = Simplify<U & Omit<T, keyof U>>;
/**
* A schema for object structs.
*/
type ObjectSchema = Record<string, Struct<any, any>>;
/**
* Infer a type from an object struct schema.
*/
type ObjectType<S extends ObjectSchema> = Simplify<Optionalize<{
[K in keyof S]: Infer<S[K]>;
}>>;
/**
* Transform an object schema type to represent a partial.
*/
type PartialObjectSchema<S extends ObjectSchema> = {
[K in keyof S]: Struct<Infer<S[K]> | undefined>;
};
/**
* A schema for any type of struct.
*/
type StructSchema<T> = [
T
] extends [
string
] ? [
T
] extends [
IsGenericString<T>
] ? null : EnumSchema<T> : T extends number | boolean | bigint | symbol | undefined | null | Function | Date | Error | RegExp ? null : T extends Map<any, any> ? null : T extends WeakMap<any, any> ? null : T extends Set<any> ? null : T extends WeakSet<any> ? null : T extends Array<infer E> ? T extends IsTuple<T> ? null : Struct<E> : T extends Promise<any> ? null : T extends object ? T extends IsRecord<T> ? null : {
[K in keyof T]: Describe<T[K]>;
} : null;
/**
* A schema for enum structs.
*/
type EnumSchema<T extends string> = {
[K in T]: K;
};
/**
* A schema for tuple structs.
*/
type TupleSchema<T> = {
[K in keyof T]: Struct<T[K]>;
};
/**
* `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<T = unknown, S = unknown> {
readonly TYPE: T;
type: string;
schema: S;
coercer: (value: unknown, context: Context) => unknown;
validator: (value: unknown, context: Context) => Iterable<Failure>;
refiner: (value: T, context: Context) => Iterable<Failure>;
entries: (value: unknown, context: Context) => Iterable<[
string | number,
unknown,
Struct<any> | Struct<never>
]>;
constructor(props: {
type: string;
schema: S;
coercer?: Coercer;
validator?: Validator;
refiner?: Refiner<T>;
entries?: Struct<T, S>["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<T, S>(value: unknown, struct: Struct<T, S>): asserts value is T;
/**
* Create a value with the coercion logic of struct and validate it.
*/
declare function create<T, S>(value: unknown, struct: Struct<T, S>): T;
/**
* Mask a value, returning only the subset of properties defined by a struct.
*/
declare function mask<T, S>(value: unknown, struct: Struct<T, S>): T;
/**
* Check if a value passes a struct.
*/
declare function is<T, S>(value: unknown, struct: Struct<T, S>): 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<T, S>(value: unknown, struct: Struct<T, S>, 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<any>;
path: Array<any>;
};
/**
* A type utility to extract the type from a `Struct` class.
*/
type Infer<T extends Struct<any, any>> = T["TYPE"];
/**
* A type utility to describe that a struct represents a TypeScript type.
*/
type Describe<T> = Struct<T, StructSchema<T>>;
/**
* A `Result` is returned from validation functions.
*/
type Result = boolean | string | Partial<Failure> | Iterable<boolean | string | Partial<Failure>>;
/**
* A `Coercer` takes an unknown value and optionally coerces it.
*/
type Coercer<T = unknown> = (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<T> = (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<T, S, C>(struct: Struct<T, S>, condition: Struct<C, any>, coercer: Coercer<C>): Struct<T, S>;
/**
* 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<T, S>(struct: Struct<T, S>, fallback: any, options?: {
strict?: boolean;
}): Struct<T, S>;
/**
* 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<T, S>(struct: Struct<T, S>): Struct<T, S>;
/**
* Ensure that a string, array, map, or set is empty.
*/
declare function empty<T extends string | any[] | Map<any, any> | Set<any>, S extends any>(struct: Struct<T, S>): Struct<T, S>;
/**
* Ensure that a number or date is below a threshold.
*/
declare function max<T extends number | Date, S extends any>(struct: Struct<T, S>, threshold: T, options?: {
exclusive?: boolean;
}): Struct<T, S>;
/**
* Ensure that a number or date is above a threshold.
*/
declare function min<T extends number | Date, S extends any>(struct: Struct<T, S>, threshold: T, options?: {
exclusive?: boolean;
}): Struct<T, S>;
/**
* Ensure that a string matches a regular expression.
*/
declare function pattern<T extends string, S extends any>(struct: Struct<T, S>, regexp: RegExp): Struct<T, S>;
/**
* Ensure that a string, array, number, date, map, or set has a size (or length, or time) between `min` and `max`.
*/
declare function size<T extends string | number | Date | any[] | Map<any, any> | Set<any>, S extends any>(struct: Struct<T, S>, min: number, max?: number): Struct<T, S>;
/**
* 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<T, S>(struct: Struct<T, S>, name: string, refiner: Refiner<T>): Struct<T, S>;
/**
* Ensure that any value passes validation.
*/
declare function any(): Struct<any, null>;
/**
* 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<T extends Struct<any>>(Element: T): Struct<Infer<T>[], T>;
declare function array(): Struct<unknown[], undefined>;
/**
* Ensure that a value is a boolean.
*/
declare function boolean(): Struct<boolean, null>;
/**
* 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<Date, null>;
/**
* 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<T extends number>(values: readonly T[]): Struct<T, {
[K in T[][number]]: K;
}>;
declare function enums<T extends string>(values: readonly T[]): Struct<T, {
[K in T[][number]]: K;
}>;
/**
* Ensure that a value is a function.
*/
declare function func(): Struct<Function, null>;
/**
* Ensure that a value is an instance of a specific class.
*/
declare function instance<T extends {
new (...args: any): any;
}>(Class: T): Struct<InstanceType<T>, null>;
/**
* Ensure that a value is an integer.
*/
declare function integer(): Struct<number, null>;
/**
* Ensure that a value matches all of a set of types.
*/
declare function intersection<A>(Structs: TupleSchema<[
A
]>): Struct<A, null>;
declare function intersection<A, B>(Structs: TupleSchema<[
A,
B
]>): Struct<A & B, null>;
declare function intersection<A, B, C>(Structs: TupleSchema<[
A,
B,
C
]>): Struct<A & B & C, null>;
declare function intersection<A, B, C, D>(Structs: TupleSchema<[
A,
B,
C,
D
]>): Struct<A & B & C & D, null>;
declare function intersection<A, B, C, D, E>(Structs: TupleSchema<[
A,
B,
C,
D,
E
]>): Struct<A & B & C & D & E, null>;
declare function intersection<A, B, C, D, E, F>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F
]>): Struct<A & B & C & D & E & F, null>;
declare function intersection<A, B, C, D, E, F, G>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G
]>): Struct<A & B & C & D & E & F & G, null>;
declare function intersection<A, B, C, D, E, F, G, H>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G,
H
]>): Struct<A & B & C & D & E & F & G & H, null>;
declare function intersection<A, B, C, D, E, F, G, H, I>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G,
H,
I
]>): Struct<A & B & C & D & E & F & G & H & I, null>;
declare function intersection<A, B, C, D, E, F, G, H, I, J>(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 intersection<A, B, C, D, E, F, G, H, I, J, K>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L, M>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(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 intersection<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>(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 is an exact value, using `===` for comparison.
*/
declare function literal<T extends boolean>(constant: T): Struct<T, null>;
declare function literal<T extends number>(constant: T): Struct<T, null>;
declare function literal<T extends string>(constant: T): Struct<T, null>;
declare function literal<T>(constant: T): Struct<T, null>;
/**
* Ensure that a value is a `Map` object, and that its keys and values are of
* specific types.
*/
declare function map(): Struct<Map<unknown, unknown>, null>;
declare function map<K, V>(Key: Struct<K>, Value: Struct<V>): Struct<Map<K, V>, null>;
/**
* Ensure that no value ever passes validation.
*/
declare function never(): Struct<never, null>;
/**
* Augment an existing struct to allow `null` values.
*/
declare function nullable<T, S>(struct: Struct<T, S>): Struct<T | null, S>;
/**
* Ensure that a value is a number.
*/
declare function number(): Struct<number, null>;
/**
* 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<Record<string, unknown>, null>;
declare function object<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
/**
* Augment a struct to allow `undefined` values.
*/
declare function optional<T, S>(struct: Struct<T, S>): Struct<T | undefined, S>;
/**
* 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<K extends string, V>(Key: Struct<K>, Value: Struct<V>): Struct<Record<K, V>, 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<RegExp, null>;
/**
* Ensure that a value is a `Set` object, and that its elements are of a
* specific type.
*/
declare function set(): Struct<Set<unknown>, null>;
declare function set<T>(Element: Struct<T>): Struct<Set<T>, null>;
/**
* Ensure that a value is a string.
*/
declare function string(): Struct<string, null>;
/**
* 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<A>(Structs: TupleSchema<[
A
]>): Struct<[
A
], null>;
declare function tuple<A, B>(Structs: TupleSchema<[
A,
B
]>): Struct<[
A,
B
], null>;
declare function tuple<A, B, C>(Structs: TupleSchema<[
A,
B,
C
]>): Struct<[
A,
B,
C
], null>;
declare function tuple<A, B, C, D>(Structs: TupleSchema<[
A,
B,
C,
D
]>): Struct<[
A,
B,
C,
D
], null>;
declare function tuple<A, B, C, D, E>(Structs: TupleSchema<[
A,
B,
C,
D,
E
]>): Struct<[
A,
B,
C,
D,
E
], null>;
declare function tuple<A, B, C, D, E, F>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F
]>): Struct<[
A,
B,
C,
D,
E,
F
], null>;
declare function tuple<A, B, C, D, E, F, G>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G
]>): Struct<[
A,
B,
C,
D,
E,
F,
G
], null>;
declare function tuple<A, B, C, D, E, F, G, H>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G,
H
]>): Struct<[
A,
B,
C,
D,
E,
F,
G,
H
], null>;
declare function tuple<A, B, C, D, E, F, G, H, I>(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<A, B, C, D, E, F, G, H, I, J>(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<A, B, C, D, E, F, G, H, I, J, K>(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<A, B, C, D, E, F, G, H, I, J, K, L>(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<A, B, C, D, E, F, G, H, I, J, K, L, M>(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<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(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<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(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<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(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<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>(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<S extends ObjectSchema>(schema: S): Struct<ObjectType<S>, S>;
/**
* Ensure that a value matches one of a set of types.
*/
declare function union<A>(Structs: TupleSchema<[
A
]>): Struct<A, null>;
declare function union<A, B>(Structs: TupleSchema<[
A,
B
]>): Struct<A | B, null>;
declare function union<A, B, C>(Structs: TupleSchema<[
A,
B,
C
]>): Struct<A | B | C, null>;
declare function union<A, B, C, D>(Structs: TupleSchema<[
A,
B,
C,
D
]>): Struct<A | B | C | D, null>;
declare function union<A, B, C, D, E>(Structs: TupleSchema<[
A,
B,
C,
D,
E
]>): Struct<A | B | C | D | E, null>;
declare function union<A, B, C, D, E, F>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F
]>): Struct<A | B | C | D | E | F, null>;
declare function union<A, B, C, D, E, F, G>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G
]>): Struct<A | B | C | D | E | F | G, null>;
declare function union<A, B, C, D, E, F, G, H>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G,
H
]>): Struct<A | B | C | D | E | F | G | H, null>;
declare function union<A, B, C, D, E, F, G, H, I>(Structs: TupleSchema<[
A,
B,
C,
D,
E,
F,
G,
H,
I
]>): Struct<A | B | C | D | E | F | G | H | I, null>;
declare function union<A, B, C, D, E, F, G, H, I, J>(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 union<A, B, C, D, E, F, G, H, I, J, K>(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 union<A, B, C, D, E, F, G, H, I, J, K, L>(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 union<A, B, C, D, E, F, G, H, I, J, K, L, M>(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 union<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(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 union<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(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 union<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(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 union<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>(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 any value passes validation, without widening its type to `any`.
*/
declare function unknown(): Struct<unknown, null>;
/**
* Create a new struct that combines the properties properties from multiple
* object structs.
*
* Like JavaScript's `Object.assign` utility.
*/
declare function assign<A extends ObjectSchema, B extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>): Struct<ObjectType<Assign<A, B>>, Assign<A, B>>;
declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>): Struct<ObjectType<Assign<Assign<A, B>, C>>, Assign<Assign<A, B>, C>>;
declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema, D extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>, D: Struct<ObjectType<D>, D>): Struct<ObjectType<Assign<Assign<Assign<A, B>, C>, D>>, Assign<Assign<Assign<A, B>, C>, D>>;
declare function assign<A extends ObjectSchema, B extends ObjectSchema, C extends ObjectSchema, D extends ObjectSchema, E extends ObjectSchema>(A: Struct<ObjectType<A>, A>, B: Struct<ObjectType<B>, B>, C: Struct<ObjectType<C>, C>, D: Struct<ObjectType<D>, D>, E: Struct<ObjectType<E>, E>): Struct<ObjectType<Assign<Assign<Assign<Assign<A, B>, C>, D>, E>>, Assign<Assign<Assign<Assign<A, B>, C>, D>, E>>;
/**
* Define a new struct type with a custom validation function.
*/
declare function define<T>(name: string, validator: Validator): Struct<T, null>;
/**
* 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<T>(fn: (value: unknown, ctx: Context) => Struct<T, any>): Struct<T, null>;
/**
* 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<T>(fn: () => Struct<T, any>): Struct<T, null>;
/**
* Create a new struct based on an existing object struct, but excluding
* specific properties.
*
* Like TypeScript's `Omit` utility.
*/
declare function omit<S extends ObjectSchema, K extends keyof S>(struct: Struct<ObjectType<S>, S>, keys: K[]): Struct<ObjectType<Omit<S, K>>, Omit<S, K>>;
/**
* 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<S extends ObjectSchema>(struct: Struct<ObjectType<S>, S> | S): Struct<ObjectType<PartialObjectSchema<S>>, PartialObjectSchema<S>>;
/**
* Create a new struct based on an existing object struct, but only including
* specific properties.
*
* Like TypeScript's `Pick` utility.
*/
declare function pick<S extends ObjectSchema, K extends keyof S>(struct: Struct<ObjectType<S>, S>, keys: K[]): Struct<ObjectType<Pick<S, K>>, Pick<S, K>>;
/**
* Define a new struct type with a custom validation function.
*
* @deprecated This function has been renamed to `define`.
*/
declare function struct<T>(name: string, validator: Validator): Struct<T, null>;
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, dynamic, lazy, omit, partial, pick, struct };