Angular 14 strictly typed reactive forms – How to type FormGroup model using existing interface

I also ran into this because I always assign my FormGroup later and I was not happy about having to add a ton of boilerplate types on every FormGroup declaration. It felt like I was repeating myself, so what I ended up doing was creating a utility type which has been working well.

export type ModelFormGroup<T> = FormGroup<{
  [K in keyof T]: FormControl<T[K]>;
}>;

This makes it easy to type the FormGroup declarations for the many data models I have. For example:

export interface UserModel {
  email: string;
  password: string;
}

// In a class...
userFormGroup: ModelFormGroup<UserModel>;

ngOnInit() {
  this.userFormGroup = this._formBuilder.nonNullable.group({
    email: [''],
    password: [''],
  });
}

Many times my data models will have more properties than I want the form to
have, so I take advantage of TypeScript’s utility types Pick, Required, Omit, etc…

export interface UserModel {
  email: string;
  password: string;
  dateAdded: Date;
  dateUpdated: Date;
}

// In a class...
userFormGroup: ModelFormGroup<Pick<UserModel, 'email' | 'password' >>;

ngOnInit() {
  this.userFormGroup = this._formBuilder.nonNullable.group({
    email: [''],
    password: [''],
  });
}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)