1
votes

I have the following Generic Type for configuring a Reactive Form taken from The Best Way to build reactive sub-forms with Angular:

export type FormGroupConfig<T> = {
    [P in keyof T]: [
            T[P] | { value: T[P]; disabled: boolean },
        (AbstractControlOptions | ValidatorFn | ValidatorFn[])?,
    ]
}

So, the type takes a Typescript model and enforces the properties/keys as the name of the form control. It works fine for a non nested model types (single FormGroup), is in the IAddress type below for example...

IAddress { 
 street: string 
 zip: string
}

However, it fails with nested types (FormGroup with nested FormGroup)

type Nok {
   relation: string
   address: IAddress
}

In the above, IAddress would represent the nested FormGroup in reactive form

How can add recursion to FormGroupConfig to allow nesting to be taken into account?

Tried some variations but now works so far.

EDIT 1:

The solution breaks when a returned FormGroup is assigned to the nested property as shown below:

const config: FormGroupConfig<Nok> = {
    relation:['', []]
    address: this.addressForm.createGroup()
}

It seems the assignment to the address property needs some further work.

1
FYI it already exists. You can try to google "typed reactive forms angular". I dont remember the library name now. - Antoniossss

1 Answers

0
votes

Maybe this generic type could be useful

type NewType<T> = [
            T | { value: T; disabled: boolean },
        (AbstractControlOptions | ValidatorFn | ValidatorFn[])?,
    ]

export type FormGroupConfig<T> = {
    [P in keyof T]: 
       T[P] extends object
            ? FormGroupConfig<T[P]>
            : NewType<T[P]>;

}

Playground