import { Type, Props, mixed } from 'io-ts';
import * as t from 'io-ts';
export interface Optional {
    optional: true;
}
/**
 * unions the passed-in type with `null` and `undefined`.
 * @see sparseType
 */
export declare const optional: <RT extends t.Mixed>(rt: RT, name?: string | undefined) => t.UnionC<[RT, t.NullC, t.UndefinedC]> & Optional;
declare type OptionalPropsTypes<P extends Props> = {
    [K in keyof P]?: P[K]['_A'];
};
declare type OptionalPropsOutputs<P extends Props> = {
    [K in keyof P]?: P[K]['_O'];
};
declare type RequiredPropsKeys<P extends Props> = {
    [K in keyof P]: P[K] extends Optional ? never : K;
}[keyof P];
declare type RequiredPropsTypes<P extends Props> = {
    [K in RequiredPropsKeys<P>]: P[K]['_A'];
};
declare type RequiredPropsOutputs<P extends Props> = {
    [K in RequiredPropsKeys<P>]: P[K]['_O'];
};
/**
 * Can be used much like `t.type` from io-ts, but any property types wrapped with `optional` from
 * this package need not be supplied. Roughly equivalent to using `t.intersection` with `t.type` and `t.partial`.
 * @example
 * const Person = sparseType({
 *   name: t.string,
 *   age: optional(t.number),
 * })
 *
 * // no error - `age` is optional
 * const bob: typeof Person._A = { name: 'bob' }
 * @param props equivalent to the `props` passed into `t.type`
 * @returns a type with `props` field, so the result can be introspected similarly to a type built with
 * `t.type` or `t.partial` - which isn't the case if you manually use `t.intersection([t.type({...}), t.partial({...})])`
 */
export declare const sparseType: <P extends Props>(props: P, name?: string | undefined) => Type<OptionalPropsTypes<P> & RequiredPropsTypes<P>, OptionalPropsOutputs<P> & RequiredPropsOutputs<P>, unknown> & {
    props: P;
};
/**
 * Validates that a value is an instance of a class using the `instanceof` operator
 * @example
 * const DateType = instanceOf(Date)
 * DateType.is(new Date())  // right(Date(...))
 * DateType.is('abc')       // left(...)
 */
export declare const instanceOf: <T>(cns: new (...args: any[]) => T) => Type<T, T, unknown>;
/**
 * A type which validates its input as a string, then decodes with `String.prototype.match`,
 * succeeding with the RegExpMatchArray result if a match is found, and failing if no match is found.
 *
 * @example
 * const AllCaps = regexp(/\b([A-Z]+)\b/)
 * AllCaps.decode('HELLO')  // right([ 'HELLO', index: 0, input: 'HELLO' ])
 * AllCaps.decode('hello')  // left(...)
 * AllCaps.decode(123)      // left(...)
 */
export declare const regexp: (v: RegExp) => Type<string[] & {
    index: number;
    input: string;
}, string, unknown>;
export declare type RegExpCodec = ReturnType<typeof regexp>;
/**
 * Like `t.type`, but fails when any properties not specified in `props` are defined.
 *
 * @example
 * const Person = strict({name: t.string, age: t.number})
 *
 * expectRight(Person.decode({name: 'Alice', age: 30}))
 * expectLeft(Person.decode({name: 'Bob', age: 30, unexpectedProp: 'abc'}))
 * expectRight(Person.decode({name: 'Bob', age: 30, unexpectedProp: undefined}))
 *
 * @param props dictionary of properties, same as the input to `t.type`
 * @param name optional type name
 *
 * @description
 * note:
 * - additional properties explicitly set to `undefined` _are_ permitted.
 * - internally, `sparseType` is used, so optional properties are supported.
 */
export declare const strict: <P extends Props>(props: P, name?: string | undefined) => Type<OptionalPropsTypes<P> & RequiredPropsTypes<P>, OptionalPropsOutputs<P> & RequiredPropsOutputs<P>, unknown>;
export {};
//# sourceMappingURL=combinators.d.ts.map