I want my FormControl
(FormGroup
/ FormArray
) be strongly typed so when I have e.g.
interface SomeSource {
id: string;
name: string;
}
and I transformed it to e.g.
let form = new FormGroup<SomeSource>({
id: new FormControl('test id'),
name1: new FormControl('test name')
});
TypeScript had thrown an error: the name
is not found on FormGroup
.
Also in the ideal world the form.value
should be of SomeSource
type (and not any
).
Problem is that there is no way to specify this generic type for any AbstractFormControl
child.
I think this is fairly easy to override FormGroup
with an own interface. However, is there a way to achieve this just using Angular? If no, are there third party solutions?
Motivation: I want to easily refactor my SomeSource
. Currently when I refactor SomeSource
interface, the form is not adapted and no error is thrown => there is a room for some bugs.
A FormArray can contain any type of controls inside it, and this includes plain form controls, FormGroup instances and even other FormArray instances.
We do not have a name to the FormGroup . The Index of the element is automatically assigned as the name for the element. Hence we use the [formGroupName]="i" where i is the index of the FormArray to bind the FormGroup to the div element. Finally, we add the controls using the formControlName directive.
setValue() sets the value of the FormArray . We need to pass an array that matches the structure of the control. Create a sample FormArray . myFormArray = new FormArray([ new FormControl(), new FormControl(), new FormControl() ]);
AbstractControllink. This is the base class for FormControl , FormGroup , and FormArray .
There is an elegant solution for your problem - leverage TypeScript declaration files (*.d.ts
) to introduce generic interfaces extending the standard form classes like AbstractControl
, FormControl
, etc. It doesn’t introduce any new functionality and has no footprint in the compiled JavaScript, but at the same time enforcing strong type checking.
It was suggested by Daniele Morosinotto in March this year and there are talks now to include it in Angular 9.
Adopting the solution is straightforward:
TypedForms.d.ts
from this gist and save it as src/typings.d.ts
in your project (Angular 6+ already knows how to use this file).FormGroupTyped<T>
, FormControlTyped<T>
, etc.) whenever you need a strong type validation (see examples in that gist or stackblitz).For more information, check out a blog post analysing available solutions for strongly typed forms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With