import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, FormGroupDirective } from '@angular/forms';
import { Observable } from 'rxjs';
declare type GetPath<M extends Partial<Record<K[0], any>>, K extends readonly string[]> = K['length'] extends 0 ? M : GetPath<M[K[0]], K extends readonly [unknown, ...infer Rest] ? Rest : []>;
declare type SplitString<S extends string, Sep extends string = '.'> = S extends `${infer H}${Sep}${infer T}` ? [H, ...SplitString<T>] : [S];
declare type ExcludeFirstArgs<T> = T extends (...arg: [infer _H, ...infer Rest]) => unknown ? Rest : never;
declare type ControlSetValue<T, F extends AbstractControl> = (value: T, ...arg: ExcludeFirstArgs<F['setValue']>) => ReturnType<F['setValue']>;
declare type ControlPatchValue<T, F extends AbstractControl> = (value: Partial<T>, ...arg: ExcludeFirstArgs<F['patchValue']>) => ReturnType<F['patchValue']>;
declare type Model = Record<string, any>;
export interface TypeFormControl<T> extends UntypedFormControl {
    value: T;
    readonly valueChanges: Observable<T>;
    setValue: ControlSetValue<T, UntypedFormControl>;
    patchValue: ControlPatchValue<T, UntypedFormControl>;
}
export interface TypeFormGroup<T extends Model> extends UntypedFormGroup {
    value: T;
    readonly valueChanges: Observable<T>;
    get<P extends string>(path: P): TypeAbstractControl<GetPath<T, SplitString<P & string>>>;
    get<P extends readonly string[] = readonly string[]>(path: P): TypeAbstractControl<GetPath<T, P>>;
    setValue: ControlSetValue<T, UntypedFormGroup>;
    patchValue: ControlPatchValue<T, UntypedFormGroup>;
    controls: {
        [key in keyof T]: T[key] extends Model ? TypeFormGroup<T[key] & Model> : TypeFormControl<GetPath<T, SplitString<key & string>>>;
    };
}
export interface TypeFormArray<T extends Model> extends UntypedFormArray {
    value: T[];
    readonly valueChanges: Observable<T[]>;
    at(index: number): TypeAbstractControl<T>;
    controls: Array<TypeFormGroup<T> & TypeFormControl<T>>;
    setValue: ControlSetValue<T[], UntypedFormArray>;
    patchValue: ControlPatchValue<T[], UntypedFormGroup>;
}
export interface TypeAbstractControl<T> extends AbstractControl {
    value: T;
    readonly valueChanges: Observable<T>;
    setValue: ControlSetValue<T, AbstractControl>;
    patchValue: ControlPatchValue<T, AbstractControl>;
}
export interface TypeFormGroupDirective<T> extends FormGroupDirective {
    value: T;
}
export {};
