/// <reference types="node" />
import { DecodeError } from './error';
export { DecodeError };
export declare class ValidationFailedError extends Error {
    error: DecodeError;
    constructor(error: DecodeError);
}
/**
 * Decode data and check it's validity using Decoder. Useful when you want to
 * check that data from clients or other outgoing sources is valid.
 *
 * To create a decoder, use one of the primitive decoders provided as a static method.
 * Then call it's deocde method on the data you want to decode.
 *
 * ```
 * const idDecoder<{id: string}> = Decoder.object({id: Decoder.string})
 *
 * idDecoder.run("2913088") // Failure, must have a field id.
 *
 * const result = idDecoder.run({id: 2913088}) // OK
 *
 * // To access the result value
 * switch(result.type) {
 *   case "OK":
 *      doThingWithId(result.value)
 *   case "FAIL":
 *      // Or if it fails you can find the reason by accessing error
 *      throw new Error(result.error)
 * }
 * ```
 *
 */
export declare class Decoder<T> {
    private decoder;
    /**
     * Transform a decoder from T to S.
     *
     * Example:
     * ```
     * const setDecoder: Decoder<Set<number>> =
     *      Decoder.array(Decoder.number).map(numberArray => new Set(numberArray))
     * ```
     */
    map: <S>(mapFunction: (arg: T) => S) => Decoder<S>;
    /**
     * Sets a default value to the decoder if it fails.
     *
     * ```
     * const nrDecoder = Decoder.number.default(0)
     *
     * nrDecoder.run(5) // OK 5
     * nrDecoder.run('hi') // OK 0
     * ```
     */
    default: <E>(value: T | E) => Decoder<T | E>;
    private static createOneOf;
    /**
     * Attempt multiple decoders in order until one succeeds. The type signature is informally:
     * ```
     * oneOf = (decoders: [Decoder<A>, Decoder<B>, ...]) => Decoder<A | B | ...>
     * ```
     *
     * Example:
     * ```
     * const enums: Decoder<"Jack" | "Sofia"> = Decoder.oneOf([
     *    Decoder.literalString("Jack"),
     *    Decoder.literalString("Sofia")
     * ])
     * enums.run("Jack") // OK
     * enums.run("Sofia") // OK
     * enums.run("Josefine") // Fail
     * ```
     */
    static oneOf: <T_1 extends Decoder<any>>(decoders: T_1[]) => Decoder<T_1 extends Decoder<infer R> ? R : never>;
    private constructor();
    /**
     * Run a decoder on data. The result is a [discriminated union](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions).    *
     *
     * Example:
     * ```
     * const userCredentials: Decoder<Credentials> = Decoder.object({...})
     * //... Somewhere else
     * const result = userCredentials.run(request.query)
     * switch(result.type) {
     *    case "OK":
     *       login(result.value)
     *    case "FAIL":
     *        throw new Error(result.error)
     * }
     * ```
     */
    run: (data: any) => {
        type: "OK";
        value: T;
    } | {
        type: "FAIL";
        error: DecodeError;
    };
    /**
     * Run a decoder on data. It will either succeed and yield the value or throw
     * an ValidationFailed error
     */
    guard: (data: any) => T;
    /**
     * Create decoders that is dependent on previous results.
     *
     * Example:
     * ```
     * const version = Decoder.field('version, Decoder.number)
     * const api = ({ version }: { version: number }): Decoder<{...}> => {
     *   switch (version) {
     *      case 0:
     *        return myFirstDecoder;
     *      case 1:
     *        return mySecondDecoder;
     *      default:
     *        return Decoder.fail('Version ${version} not supported')
     * }
     * };
     * const versionedApi = version.then(api);
     * ```
     */
    then: <S>(dependentDecoder: (res: T) => Decoder<S>) => Decoder<S>;
    /**
     * Add an extra predicate to the decoder. Optionally add a failure message
     * that overrides the earlier failure message.
     *
     * Example:
     * ```
     * const naturalNumber = Decoder.number.satisfy({
     *  predicate: n => n>0
     *  failureMessage: `Not a natural number`
     * })
     * naturalNumber.run(5) // OK, 5
     * naturalNumber.run(-1) // FAIL, Not a natural number
     * ```
     */
    satisfy: ({ predicate, failureMessage, }: {
        predicate: (arg: T) => boolean;
        failureMessage?: string | undefined;
    }) => Decoder<T>;
    /**
     * A decoder for numbers.
     *
     * Example:
     * ```
     * Decoder.number.run(5) // OK
     * Decoder.number.run('5') // OK
     * Decoder.number.run('hi') // FAIL
     * ```
     */
    static number: Decoder<number>;
    /**
     * A decoder for iso dates. Use `Decoder.date` to also support timestamps.
     *
     * Example:
     * ```
     * Decoder.date.run(new Date()) // OK
     * Decoder.date.run("abra") // FAIL
     * Decoder.date.run("2020-01-13T18:27:35.817Z") // OK
     * Decoder.date.run(123) // FAIL
     * Decoder.date.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL, format is not supported
     * ```
     */
    static isoDate: Decoder<Date>;
    /**
     * A decoder for timestamps.
     *
     * Example:
     * ```
     * Decoder.date.run(123) // OK (Timestamp)
     * Decoder.date.run(new Date()) // FAIL
     * Decoder.date.run("abra") // FAIL
     * Decoder.date.run("2020-01-13T18:27:35.817Z") // FAIL
     * Decoder.date.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL
     * ```
     */
    static timestamp: Decoder<number>;
    /**
     * A decoder for dates. Decoding UTC time that is formatted using
     * `toUTCString()` is not supported; Javascript's date parser parses UTC strings
     * wrong.
     *
     * Example:
     * ```
     * Decoder.date.run(123) // OK (Timestamp)
     * Decoder.date.run(new Date()) // OK
     * Decoder.date.run("abra") // FAIL
     * Decoder.date.run("2020-01-13T18:27:35.817Z") // OK
     * Decoder.date.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL, format is not supported
     * ```
     */
    static date: Decoder<Date>;
    /**
     * A decoder that accepts undefined.
     *
     * Example:
     * ```
     * Decoder.undefined.run(null) // FAIL
     * Decoder.undefined.run(5) // FAIL
     * Decoder.undefined.run(undefined) // OK
     *```
     */
    static undefined: Decoder<undefined>;
    /**
     * A decoder that accepts null.
     *
     * Example:
     * ```
     * Decoder.null.run(undefined) // FAIL
     * Decoder.null.run(5) // FAIL
     * Decoder.null.run(null) // OK
     *```
     */
    static null: Decoder<null>;
    /**
     * A decoder that accepts a Buffer.
     *
     * Example:
     * ```
     * Decoder.null.run(undefined) // FAIL
     * Decoder.null.run(5) // FAIL
     * Decoder.null.run(Buffer.from('Hello world')) // OK
     * Decoder.null.run(<Buffer 68 65 6c 6c 6f>) // OK
     *```
     */
    static buffer: Decoder<Buffer>;
    /**
     * Decodes a string.
     *
     * Example:
     * ```
     * Decoder.string.run('hi') // OK
     * Decoder.string.run(5) // Fail
     * ```
     */
    static string: Decoder<string>;
    /**
     * Decodes the exact string and sets it to a string literal type. Useful for
     * parsing unions.
     *
     * Example:
     * ```
     * const jackOrSofia: Decoder<'Jack' | 'Sofia'> = Decoder.oneOf([
     *    Decoder.literalString('Jack'),
     *    Decoder.literalString('Sofia')
     * ])
     * jackOrSofia.run('Jack') // OK
     * jackOrSofia.run('Josephine') // FAIL
     * ```
     */
    static literalString: <T_1 extends string>(str: T_1) => Decoder<T_1>;
    /**
     * Takes a decoder and returns an optional decoder.
     *
     * Example:
     * ```
     * const optionalNumber = Decoder.optional(Decoder.number)
     * optionalNumber.run(5) //OK
     * optionalNumber.run(undefined) //OK
     * optionalNumber.run(null) //OK
     * optionalNumber.run('hi') //FAIL
     * ```
     */
    static optional: <T_1>(decoder: Decoder<T_1>) => Decoder<T_1 | undefined>;
    /**
     * Create a decoder that always fails with a message.
     */
    static fail: <T_1>(message: string) => Decoder<T_1>;
    /**
     * Create a decoder that always suceeds and returns T.
     */
    static ok: <T_1>(value: T_1) => Decoder<T_1>;
    /**
     * Decodes the exact number and sets it to a number literal type.
     *
     * Example:
     * ```
     * const versionDecoder: Decoder<1 | 2> = Decoder.oneOf([
     *    Decoder.literalNumber(1),
     *    Decoder.literalNumber(2)
     * ])
     *
     * versionDecoder.run(1) // OK
     * versionDecoder.run(3) // FAIL
     * ```
     */
    static literalNumber: <T_1 extends number>(number: T_1) => Decoder<T_1>;
    /**
     * Create an array decoder given a decoder for the elements.
     *
     * Example:
     * ```
     * Decoder.array(Decoder.string).run(['hello','world']) // OK
     * Decoder.array(Decoder.string).run(5) // Fail
     * ```
     */
    static array: <T_1>(decoder: Decoder<T_1>) => Decoder<T_1[]>;
    /**
     * Create a decoder for booleans.
     *
     * Example:
     * ```
     * Decoder.boolean.run(true) // succeeds
     * Decoder.boolean.run('false') // succeeds
     * Decoder.boolean.run(1) // fails
     * ```
     */
    static boolean: Decoder<boolean>;
    /**
     * Decode the value of a specific key in an object using a given decoder.
     *
     * Example:
     * ```
     * const versionDecoder = Decoder.field("version", Decoder.number)
     *
     * versionDecoder.run({version: 5}) // OK, 5
     * versionDecoder.run({name: "hi"}) // fail
     * ```
     *
     */
    static field: <T_1>(key: string, decoder: Decoder<T_1>) => Decoder<T_1>;
    /**
     * A decoder that accepts anything.
     */
    static any: Decoder<unknown>;
    /**
     * run a decoder on each item in an array, collecting the amount of successful and failed decodings.
     *
     * ```
     * example:
     *
     * Decoder.number.sequence([1,3,4,"hello"]) // => {successful: [1,2,3], failed: ["hello"]}
     * ```
     */
    sequence: (array: unknown[]) => {
        successful: T[];
        failed: unknown[];
    };
    /**
     * Decode values of an object where the keys are unknown.
     *
     * Example:
     * ```
     * const userDecoder = Decoder.object({age: Decoder.number})
     * const usersDecoder = Decoder.dict(userDecoder)
     *
     * usersDecoder.run({emelie: {age: 32}, bob: {age: 50}}) // OK, {emelie: {age: 32}, bob: {age: 50}}
     * usersDecoder.run({name: 'emelie', age: 32}) // fail
     * ```
     *
     */
    static dict: <T_1>(decoder: Decoder<T_1>) => Decoder<{
        [key: string]: T_1;
    }>;
    /**
     * Create a decoder for a type T.
     *
     * Argument "object" is a [Mapped
     * type](https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types),
     * an object containing only decoders for each field.
     * ```typescript
     * {name: Decoder.string} // Ok parameter
     * {name: Decoder.string, email: 'email@email'} // Type error, email must be decoder
     * ```
     *
     * Example:
     * ```
     * interface User {
     *    name: string
     *    email: string
     * }
     *
     * // typechecks
     * const decodeUser: Decoder<User> = Decoder.object({name: Decoder.string, email: Decoder.email})
     * decodeUser.run({name: "Jenny", email: "fakemail@fake.com"}) // OK
     * decodeUser.run({nm: "Bad"}) // FAIL
     *
     * // will not typecheck, object must have the same field names as user and
     * // only contain decoders.
     * const decodeUser: Decoder<User> = Decoder.object({nem: 'Hi'})
     * ```
     *
     */
    static object: <T_1>(object: { [K in keyof T_1]: Decoder<T_1[K]>; }) => Decoder<T_1>;
}
/**
 * Deduce the return type of a decoder. If there is a deep nesting of objects
 * the type will be inferred but will not display correctly in the signature.
 *
 * Example:
 * ```
 * const paramDecoder = Decoder.object({
 *  body: userDecoder
 * })
 * const handleRequest = (params: DecodedValue<typeof paramDecoder>) => {
 *  // params.body is inferred
 * }
 * ```
 *
 */
export declare type DecodedValue<T> = T extends Decoder<infer U> ? U : never;
