angular: Wrong FormControl type inference when created with FormBuild through group() with Validators and an array as value

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

When creating a FormGroup with the new ng14 FormBuilder, if you try to add a control with both array value and validator(s) the infered type for this control become wrong. It seems the validator(s) are considered as value so we get a bad union typing.

/**
 * Wrong type!
 * FormGroup<{
 *   test: FormControl<number[] | ((control: AbstractControl<any, any>) => ValidationErrors | null)>;
 *  }>
 */
const form = fb.nonNullable.group({
  test: [[1,2,3], Validators.required]
})

If you use the long way to add control, everything works just fine but we loose FormBuilder.group() shorthand synthax benefit

/**
 * Good type!
 * FormGroup<{
 *   test: FormControl<number[]>;
 *  }>
 */
const form = fb.nonNullable.group({
  test: fb.nonNullable.control([1,2,3], Validators.required)
})

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-ivy-cw97ml?file=src/app/app.component.ts

Please provide the exception or error you saw

Type 'FormGroup<{ test: FormControl<number[] | ((control: AbstractControl<any, any>) => ValidationErrors)>; }>' is not assignable to type 'FormGroup<{ test: FormControl<number[]>; }>'.
  Types of property 'controls' are incompatible.
    Type '{ test: FormControl<number[] | ((control: AbstractControl<any, any>) => ValidationErrors)>; }' is not assignable to type '{ test: FormControl<number[]>; }'.(2322)

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 14.0.2
Node: 16.15.1
Package Manager: npm 8.12.2 
OS: linux x64

Angular: 14.0.2
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, material, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1400.2
@angular-devkit/build-angular   14.0.2
@angular-devkit/core            14.0.2
@angular-devkit/schematics      14.0.2
@angular/flex-layout            13.0.0-beta.38
@schematics/angular             14.0.2
rxjs                            7.5.5
typescript                      4.7.4

Anything else?

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 8
  • Comments: 16 (9 by maintainers)

Most upvoted comments

After trying many ways of initializing forms since version 14, I think the form builder doesn’t bring much value than instanciate directly form controls. Eventually the only benefit is the .nonNullable shortcut. This benefit could be replaced with an eventual new NonNullableFormControl or NonNullableFormArray class (in the case of FormArrays I think it would be better to declare them non nullable and initialize them with an empty array by default) But what is the point of this comment ? IMO dropping FormBuilder feature whould give Angular team more time and resource to focus on other more complex and needed features

Of course it’s just my opinion

@destus90 and @MikaStark: This should now be fixed and released in 14.2.0-rc.0. Does it solve the issue for both of you? Thanks!

@iErKy Can you please open a new issue? That will help us keep our topics separate. Thanks!

I think this happens not only when you are using an array value for your FormControl.

For this case we are getting a bad typing too:

const form = this.fb.group({
  analyzedFeatures: [null, Validators.required],
});

image

Yes, if your FormControl takes an array value, use new FormControl<string[]>([]).