angulartypescriptangular-forms

Deriving the type of the value of a typed FormGroup in Angular


With the new typed form controls in Angular, we can do this:

interface MyFormGroup {
    id: FormControl<number | null>;
    name: FormControl<string | null>;
    email: FormControl<string | null>;
}

Which defines a type for each FormControl in the following FormGroup:

myFormGroup = new FormGroup<MyFormGroup>({
    id: new FormControl(42),
    name: new FormControl('Arthur'),
    email: new FormControl('arthur@dent.com')
});

The type of the value of this FormGroup would be:

Partial<{
    id: number | null;
    name: string | null;
    email: string | null;
}>

If I want to use the value of the FormGroup in a function, is there a shortcut to getting the type of the value, or must this be defined separately, e.g.

interface MyFormGroupValue {
    id: number | null;
    name: string | null;
    email: string | null;
}

myFunction(myFormGroupValue: MyFormGroupValue){
    console.log(myFormGroupValue);
}

Put another way, is it possible to derive the type MyFormGroupValue from MyFormGroup?


Solution

  • Using a mapped type and the infer keyword will do the trick.

    type ExtractFormControl<T> = {
        [K in keyof T]: T[K] extends FormControl<infer U> ? U : T[K]
    }
    
    type MyFormGroupValue = ExtractFormControl<MyFormGroup>
    // type MyFormGroupValue = {
    //     id: number | null;
    //     name: string | null;
    //     email: string | null;
    // }
    

    Playground