2022 Update (Angular 14): Typed Reactive Forms
With the latest update of Angular, strict types for reactive forms have been implemented! and there is no need for a workaround.
If you are using formBuilder
service for creating your forms you can assign a strict type to it like the following:
type myType = 'typeA' | 'typeB' | 'typeC';
public myForm = this.fb.control<myType>('typeA');
Ang if you prefer to create a formGroup
regardless of formBuilder
service, this is how you can achieve that:
interface User {
name: FormControl<string>;
email: FormControl<string>;
isAdmin: FormControl<boolean>;
}
public user: FormGroup<User> = new FormGroup<User>({
name: new FormControl('', {nonNullable: true}),
email: new FormControl('', {nonNullable: true}),
isAdmin: new FormControl(false, {nonNullable: true}),
});
Please keep in mind that if you do not specify the nonNullable
attribute, you might get an error in your template about your value being null
. especially when you want to bind your form control's value to something.
Angular will automatically check for type system even if you do not explicitly write down the type like the following:
const cat = new FormGroup({
name: new FormGroup({
first: new FormControl('Barb'),
last: new FormControl('Smith'),
}),
lives: new FormControl(9),
});
// Type-checking for forms values!
// TS Error: Property 'substring' does not exist on type 'number'.
let remainingLives = cat.value.lives.substring(1);
// Optional and required controls are enforced!
// TS Error: No overload matches this call.
cat.removeControl('lives');
// FormGroups are aware of their child controls.
// name.middle is never on cat
let catMiddleName = cat.get('name.middle');
You can learn more about this at the Angular 14 release update on their blog here