export type Subscription = { [key: string]: boolean | undefined; }; export type Subscriber = (value: V) => void; export type IsEqual = (a: any, b: any) => boolean; export interface AnyObject { [key: string]: any; } export type ValidationErrors = AnyObject | undefined; export type SubmissionErrors = AnyObject | undefined; export interface FormSubscription extends Subscription { active?: boolean; dirty?: boolean; dirtyFields?: boolean; dirtyFieldsSinceLastSubmit?: boolean; dirtySinceLastSubmit?: boolean; modifiedSinceLastSubmit?: boolean; error?: boolean; errors?: boolean; hasSubmitErrors?: boolean; hasValidationErrors?: boolean; initialValues?: boolean; invalid?: boolean; modified?: boolean; pristine?: boolean; submitError?: boolean; submitErrors?: boolean; submitFailed?: boolean; submitting?: boolean; submitSucceeded?: boolean; touched?: boolean; valid?: boolean; validating?: boolean; values?: boolean; visited?: boolean; } export interface FormState, InitialFormValues extends Partial = Partial> { active?: undefined | keyof FormValues; dirty?: boolean; dirtyFields?: { [key: string]: boolean; }; dirtyFieldsSinceLastSubmit?: { [key: string]: boolean; }; dirtySinceLastSubmit?: boolean; error?: any; errors?: ValidationErrors; hasSubmitErrors?: boolean; hasValidationErrors?: boolean; initialValues?: InitialFormValues; invalid?: boolean; modified?: { [key: string]: boolean; }; modifiedSinceLastSubmit?: boolean; pristine?: boolean; submitError?: any; submitErrors?: SubmissionErrors; submitFailed?: boolean; submitSucceeded?: boolean; submitting?: boolean; touched?: { [key: string]: boolean; }; valid?: boolean; validating?: boolean; values: FormValues; visited?: { [key: string]: boolean; }; } export type FormSubscriber, InitialFormValues extends Partial = Partial> = Subscriber>; export interface FieldState { active?: boolean; blur: () => void; change: (value: FieldValue | undefined) => void; data?: AnyObject; dirty?: boolean; dirtySinceLastSubmit?: boolean; error?: any; focus: () => void; initial?: FieldValue; invalid?: boolean; length?: number; modified?: boolean; modifiedSinceLastSubmit?: boolean; name: string; pristine?: boolean; submitError?: any; submitFailed?: boolean; submitSucceeded?: boolean; submitting?: boolean; touched?: boolean; valid?: boolean; validating?: boolean; value?: FieldValue; visited?: boolean; } export interface FieldSubscription { active?: boolean; data?: boolean; dirty?: boolean; dirtySinceLastSubmit?: boolean; error?: boolean; initial?: boolean; invalid?: boolean; length?: boolean; modified?: boolean; modifiedSinceLastSubmit?: boolean; pristine?: boolean; submitError?: boolean; submitFailed?: boolean; submitSucceeded?: boolean; submitting?: boolean; touched?: boolean; valid?: boolean; validating?: boolean; value?: boolean; visited?: boolean; } export type FieldSubscriber = Subscriber>; export type Subscribers = { index: number; entries: { [key: number]: { subscriber: Subscriber; subscription: Subscription; notified: boolean; }; }; }; export type Unsubscribe = () => void; export type FieldValidator = (value: FieldValue, allValues: object, meta?: FieldState) => any | Promise; export type GetFieldValidator = () => FieldValidator | undefined; export interface FieldConfig { afterSubmit?: () => void; beforeSubmit?: () => void | false; data?: any; defaultValue?: any; getValidator?: GetFieldValidator; initialValue?: any; isEqual?: IsEqual; silent?: boolean; validateFields?: string[]; async?: boolean; } export type RegisterField> = (name: F, subscriber: FieldSubscriber, subscription: FieldSubscription, config?: FieldConfig) => Unsubscribe; export interface InternalFieldState { active: boolean; afterSubmit?: () => void; asyncValidationCount: number; asyncValidationKey: number; beforeSubmit?: () => void | false; blur: () => void; change: (value: any) => void; data: AnyObject; focus: () => void; instanceId?: number; isEqual: IsEqual; lastFieldState?: FieldState; length?: any; modified: boolean; modifiedSinceLastSubmit: boolean; name: string; touched: boolean; validateFields?: string[]; validators: { [index: number]: GetFieldValidator; }; valid: boolean; validating: boolean; visited: boolean; } export interface InternalFormState> { active?: string; asyncErrors: AnyObject; dirtySinceLastSubmit: boolean; modifiedSinceLastSubmit: boolean; error?: any; errors: ValidationErrors; initialValues?: AnyObject; lastSubmittedValues?: AnyObject; pristine: boolean; resetWhileSubmitting: boolean; submitError?: any; submitErrors?: AnyObject; submitFailed: boolean; submitSucceeded: boolean; submitting: boolean; valid: boolean; validating: number; values: FormValues; } export type ConfigKey = "debug" | "destroyOnUnregister" | "initialValues" | "keepDirtyOnReinitialize" | "mutators" | "onSubmit" | "validate" | "validateOnBlur" | "callbackScheduler" | "ignoreUnregister"; export interface FormApi, InitialFormValues extends Partial = Partial> { batch: (fn: () => void) => void; blur: (name: keyof FormValues) => void; change: (name: F, value?: FormValues[F]) => void; destroyOnUnregister: boolean; focus: (name: keyof FormValues) => void; initialize: (data: InitialFormValues | ((values: FormValues) => InitialFormValues)) => void; isValidationPaused: () => boolean; getFieldState: (field: F) => FieldState | undefined; getRegisteredFields: () => string[]; getState: () => FormState; mutators: Record any>; pauseValidation: () => void; registerField: RegisterField; reset: (initialValues?: InitialFormValues) => void; resetFieldState: (name: keyof FormValues) => void; restart: (initialValues?: InitialFormValues) => void; resumeValidation: () => void; setConfig: (name: K, value: Config[K]) => void; setCallbackScheduler: (scheduler?: (callback: () => void) => void) => void; submit: () => Promise | undefined; subscribe: (subscriber: FormSubscriber, subscription: FormSubscription) => Unsubscribe; /** * Subscribes to the state of a specific field in the form. * @param name - The name of the field to subscribe to. * @param onChange - A callback function that is called whenever the field state changes. * @param subscription - An object specifying which parts of the field state to subscribe to. * @returns A function to unsubscribe from the field state updates. */ subscribeFieldState: (name: F, onChange: () => void, subscription: FieldSubscription) => Unsubscribe; /** * Retrieves a snapshot of the current state of a specific field. * @param name - The name of the field to retrieve the state for. * @returns The current state of the field, or undefined if the field is not registered. */ getFieldSnapshot: (name: F) => FieldState | undefined; /** * Subscribes to the state of the entire form. * @param onChange - A callback function that is called whenever the form state changes. * @param subscription - An object specifying which parts of the form state to subscribe to. * @returns A function to unsubscribe from the form state updates. */ subscribeFormState: (onChange: () => void, subscription: FormSubscription) => Unsubscribe; /** * Retrieves a snapshot of the current state of the form. * @returns The current state of the form, represented by `FormState`. */ getFormSnapshot: () => FormState; ignoreUnregister: boolean; } export type DebugFunction, InitialFormValues extends Partial = Partial> = (state: FormState, fieldStates: { [key: string]: FieldState; }) => void; export interface MutableState, InitialFormValues extends Partial = Partial> { fieldSubscribers: { [key: string]: Subscribers>; }; fields: { [key: string]: InternalFieldState; }; formState: InternalFormState; lastFormState?: FormState; } export type GetIn = (state: object, complexKey: string) => any; export type SetIn = (state: object, key: string, value: any, destroyArrays?: boolean) => object; export type ChangeValue, InitialFormValues extends Partial = Partial> = (state: MutableState, name: string, mutate: (value: any) => any) => void; export type RenameField, InitialFormValues extends Partial = Partial> = (state: MutableState, from: string, to: string) => void; export interface Tools, InitialFormValues extends Partial = Partial> { changeValue: ChangeValue; getIn: GetIn; renameField: RenameField; resetFieldState: (name: string) => void; setIn: SetIn; shallowEqual: IsEqual; } export type Mutator, InitialFormValues extends Partial = Partial> = (args: any[], state: MutableState, tools: Tools) => any; export interface Config, InitialFormValues extends Partial = Partial> { debug?: DebugFunction; destroyOnUnregister?: boolean; initialValues?: InitialFormValues; keepDirtyOnReinitialize?: boolean; mutators?: { [key: string]: Mutator; }; onSubmit: (values: FormValues, form: FormApi, callback?: (errors?: SubmissionErrors) => void) => SubmissionErrors | Promise | void; validate?: (values: FormValues) => ValidationErrors | Promise; validateOnBlur?: boolean; callbackScheduler?: (callback: () => void) => void; ignoreUnregister?: boolean; } export type Decorator, InitialFormValues extends Partial = Partial> = (form: FormApi) => Unsubscribe; export type StateFilter = (state: T, previousState: T | undefined, subscription: Subscription, force: boolean) => T | undefined;