import { InjectionToken } from '@angular/core';
import {
  AbstractControl,
  AbstractControlOptions,
  AsyncValidatorFn,
  FormArray,
  FormControl,
  FormGroup,
  ValidatorFn,
} from '@angular/forms';
interface ITypedFormArray<_T, E = any>
  extends Iterable<AbstractControl>,
    FormArray {
  add(value: E): any;
}
interface ITypedFormControl<T> extends FormControl {
  value: T;
}
//@ts-ignore
interface ITypedFormGroup<T> extends FormGroup {
  controls: ITypedFormGroupControls<T>;
  setReadonly(value: boolean): any;
}
declare type ITypedFormGroupControls<T> = {
  [P in keyof T]?: T[P] extends (infer E)[]
    ? ITypedFormArray<T, E>
    : T[P] extends object
    ? ITypedFormGroup<T[P]>
    : ITypedFormControl<T[P]>;
};
export declare class TypedFormGroup<T>
  extends FormGroup
  implements ITypedFormGroup<T>
{
  //@ts-ignore
  controls: ITypedFormGroupControls<T>;
  constructor(
    controls: ITypedFormGroupControls<T>,
    validatorOrOpts?:
      | ValidatorFn
      | ValidatorFn[]
      | AbstractControlOptions
      | null,
    asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null
  );
  setReadonly(_value: boolean): void;
}
interface CreateTypedControlsOptions {
  ignoreFields: string[];
}
declare type ITypedFormBuilderOptions = CreateTypedControlsOptions;
export declare function typedFormBuilderFactory<T extends object>(
  defaultValue: T,
  options?: ITypedFormBuilderOptions
): ITypedFormBuilder<T> | null;
export declare const TYPED_FORM_BUILDER: InjectionToken<ITypedFormBuilder<any>>;
declare type ITypedFormBuilderValue<T> = {
  [P in keyof T]?: T[P] extends (infer E)[]
    ? ITypedFormArray<T[P], E>
    : T[P] extends object
    ? ITypedFormBuilderValue<T[P]>
    : ITypedFormControl<T[P]> | T[P];
};
export interface ITypedFormBuilder<T> {
  value: ITypedFormBuilderValue<T>;
  formGroup: ITypedFormGroup<T>;
}
export {};
