Starting from Angular 14, reactive forms are now strictly typed by default (Typed Forms). This new feature is quite convenient. I recently created a basic login form as shown below.
form = this.fb.group({
username: ['', [Validators.required]],
password: ['', [Validators.required]],
rememberMe: [true]
});
submit() {
this.authenticationService.login(this.form.value).subscribe();
In the service file, my code looks like this:
login(data: { username: string; password: string; rememberMe: boolean }): Observable<any> {
// Here goes the logic for authentication
}
Typescript correctly infers the type of form
to be:
form: FormGroup<{username: FormControl<string>, password: FormControl<string>, rememberMe: FormControl<boolean>}>
This setup seems fine, but there's a problem with this.form.value
since its type is
Partial<{ username: string; password: string; rememberMe: boolean; }>
. This inconsistency results in a TypeScript error message:
Argument of type 'Partial<{ username: string; password: string; rememberMe: boolean; }>' is not assignable to parameter of type '{ username: string; password: string; rememberMe: boolean; }'. Property 'username' is optional in type 'Partial<{ username: string; password: string; rememberMe: boolean; }>' but required in type '{ username: string; password: string; rememberMe: boolean; }'.
I'm wondering if there's a way to specify while defining the formgroup that these fields will always be present in the formgroup value. Currently, I am forced to do typecasting like so:
this.form.value as {username: string; rememberMe: boolean; password: string}
Although this workaround gets the job done, I'm curious if it needs to be applied to every form?