Typed Reactive Forms in Angular — No Longer a Type Dream 💭
One of Angular 14’s most sought-after features is here— Typed Reactive Forms. You can begin experimenting with it now by creating a new Angular 14 project:
npx @angular/cli@next new angular14
Let’s review what’s new in this area:
FormControl
We pass a string, so the form control is automatically inferred as FormControl<string | null>
. TypeScript automatically enforces this type throughout the FormControl
API.
You may be wondering where the null
type comes from. The reason is that if you don’t pass a value to control.reset()
, it’ll default to null
. We can change this behavior by setting the new nonNullable
option to true
:
You can also pass a type
explicitly if you need to:
FormGroup
The type undefined
is added because if the control is disabled
, it’ll not be included in the value
object. We can bypass it using the getRawValue()
method:
A form may have controls, which can be added and removed at runtime. These controls can be represented by optional fields:
FormRecord
There are some cases where FormGroup
usage doesn’t match the above pattern since the keys are unknown beforehand. The new FormRecord
entity was added for such cases:
FormArray
Each control type in the above FormArray
is FormControl<string | null>
. UntypedFormArray
must be used if you have multiple different element types within the array:
FormBuilder
Similar to the examples above, the FormBuilder
class has been upgraded to support the new types.
In addition, we can use the new injectable NonNullableFormBuilder
to save the boilerplate when we want to use the nonNullable
option in every control:
It’s much cleaner this way. Alternatively, you can use the nonNullable
property:
Migration
Angular provides untyped versions to enable incremental migrations:
Angular 14 includes a migration that replaces all controls classes with their untyped equivalents.
Bonus
We can define a type
that maps a model
to a strict form group. To demonstrate, here is a minimal version of my reactive forms library:
Follow me on Medium or Twitter to read more about Angular and JS!