import { AbstractControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { FormArray } from './form-array';
import { FormGroup } from './form-group';
import { FormControl } from './form-control';
/**
 * This type marks a property of a form model as property
 * which is intended for an instance of `FormControl`.
 *
 * If a property of your form model have a primitive type,
 * in appropriate form field the instance of `FormControl` will be automatically assigned.
 * But if the property have a type that extends `object` - you need `Control<T>`.
 *
 * ### Example:
```ts
import { FormBuilder, Control } from '@ng-stack/forms';

const fb = new FormBuilder();

// Form Model
interface Person {
  id: number;
  name: string;
  birthDate: Control<Date>; // Here should be FormControl, instead of a FormGroup
}

const form = fb.group<Person>({
  id: 123,
  name: 'John Smith',
  birthDate: new Date(1977, 6, 30),
});

const birthDate: Date = form.value.birthDate;
```
 * ## External form model
 *
 * If the form model interface comes from an external library, you can do the following:
 *
```ts
import { FormBuilder, Control } from '@ng-stack/forms';

const fb = new FormBuilder();

// External Form Model
interface ExternalPerson {
  id: number;
  name: string;
  birthDate: Date;
}

const configForm: ExternalPerson = {
  id: 123,
  name: 'John Smith',
  birthDate: new Date(1977, 6, 30),
};

interface Person extends ExternalPerson {
  birthDate: Control<Date>;
}

const form = fb.group<Person>(configForm); // `Control<Date>` type is compatible with `Date` type.

const birthDate: Date = form.value.birthDate; // `Control<Date>` type is compatible with `Date` type.
```
 */
export declare type Control<T extends object> = T & UniqToken;
declare const sym: unique symbol;
interface UniqToken {
    [sym]: never;
}
/**
 * Extract `keyof T` with string keys.
 */
export declare type StringKeys<T> = Extract<keyof T, string>;
declare type ExtractAny<T> = T extends Extract<T, string & number & boolean & object & null & undefined> ? any : never;
/**
 * This type is a conditional type that automatically detects
 * appropriate types for form controls by given type for its generic.
 */
export declare type ControlType<T, V extends object = ValidatorsModel> = [T] extends [ExtractAny<T>] ? FormGroup<any, V> | FormControl<any, V> | FormArray<any, V> : [T] extends [Control<infer ControlModel>] ? FormControl<ControlModel, V> : [T] extends [Array<infer Item>] ? FormArray<Item, V> : [T] extends [object] ? FormGroup<T, V> : FormControl<T, V>;
export declare type FormControlState<T> = null | ExtractModelValue<T> | {
    value: null | ExtractModelValue<T>;
    disabled: boolean;
};
/**
 * Clears the form model from `Control<T>` type.
 */
export declare type ExtractModelValue<T> = [T] extends [ExtractAny<T>] ? any : [T] extends [Array<infer Item>] ? Array<ExtractModelValue<Item>> : [T] extends [Control<infer ControlModel>] ? ControlModel : [T] extends [object] ? ExtractGroupValue<T> : T;
export declare type ExtractControlValue<T> = [T] extends [Control<infer ControlModel>] ? ControlModel : T;
/**
 * Clears the form model (as object) from `Control<T>` type.
 */
export declare type ExtractGroupValue<T extends object> = {
    [P in keyof T]: ExtractModelValue<T[P]>;
};
export declare type ExtractGroupStateValue<T extends object> = {
    [P in keyof T]: FormControlState<T[P]>;
};
/**
 * Form builder control config.
 */
export declare type FbControlConfig<T, V extends object = ValidatorsModel> = [T] extends [ExtractAny<T>] ? FormGroup<any, V> | FbControl<any, V> | FormArray<any, V> : [T] extends [Control<infer ControlModel>] ? FbControl<ControlModel, V> : [T] extends [Array<infer Item>] ? FormArray<Item, V> : [T] extends [object] ? FormGroup<T, V> : FbControl<T, V>;
/**
 * Form builder control.
 */
export declare type FbControl<T, V extends object = ValidatorsModel> = ExtractModelValue<T> | FormControlState<T> | [
    FormControlState<T>,
    (ValidatorFn | ValidatorFn[] | AbstractControlOptions)?,
    (AsyncValidatorFn | AsyncValidatorFn[])?
] | FormControl<T, V>;
/**
 * The validation status of the control. There are four possible
 * validation status values:
 *
 * * **VALID**: This control has passed all validation checks.
 * * **INVALID**: This control has failed at least one validation check.
 * * **PENDING**: This control is in the midst of conducting a validation check.
 * * **DISABLED**: This control is exempt from validation checks.
 *
 * These status values are mutually exclusive, so a control cannot be
 * both valid AND invalid or invalid AND disabled.
 */
export declare type Status = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED';
/**
 * Interface for options provided to an `AbstractControl`.
 */
export interface AbstractControlOptions<T extends object = any> {
    /**
     * The list of validators applied to a control.
     */
    validators?: ValidatorFn<T> | ValidatorFn<T>[] | null;
    /**
     * The list of async validators applied to control.
     */
    asyncValidators?: AsyncValidatorFn<T> | AsyncValidatorFn<T>[] | null;
    /**
     * The event name for control to update upon.
     */
    updateOn?: 'change' | 'blur' | 'submit';
}
/**
 * A function that receives a control and synchronously returns a map of
 * validation errors if present, otherwise null.
 */
export declare type ValidatorFn<T extends object = any> = (control: AbstractControl) => ValidationErrors<T> | null;
/**
 * A function that receives a control and returns a Promise or observable
 * that emits validation errors if present, otherwise null.
 */
export declare type AsyncValidatorFn<T extends object = any> = (control: AbstractControl) => Promise<ValidationErrors<T> | null> | Observable<ValidationErrors<T> | null>;
/**
 * Defines the map of errors returned from failed validation checks.
 */
export declare type ValidationErrors<T extends object = any> = T;
/**
 * The default validators model, it includes almost all static properties of `Validators`,
 * excludes: `prototype`, `compose`, `composeAsync` and `nullValidator`.
 *
 * ### Usage
 *
```ts
const formControl = new FormControl<string, ValidatorsModel>('some value');
// OR
const formGroup = new FormGroup<any, ValidatorsModel>({});
// OR
const formArray = new FormArray<any, ValidatorsModel>([]);
```
 */
export declare class ValidatorsModel {
    min: {
        min: number;
        actual: number;
    };
    max: {
        max: number;
        actual: number;
    };
    required: true;
    email: true;
    minlength: {
        requiredLength: number;
        actualLength: number;
    };
    maxlength: {
        requiredLength: number;
        actualLength: number;
    };
    pattern: {
        requiredPattern: string;
        actualValue: string;
    };
    fileRequired: {
        requiredSize: number;
        actualSize: number;
        file: File;
    };
    filesMinLength: {
        requiredLength: number;
        actualLength: number;
    };
    filesMaxLength: {
        requiredLength: number;
        actualLength: number;
    };
    fileMaxSize: {
        requiredSize: number;
        actualSize: number;
        file: File;
    };
}
export {};
