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: [''],
});
}