angular/packages/forms/test
Dylan Hunn f18e1739b8 fix(forms): allow FormBuilder.group(...) to accept optional fields. (#46253)
Consider the case in which `FormBuilder` is used to construct a group with an optional field:

```
const controls = { name: fb.control('') };
const foo: FormGroup<{
  name: FormControl<string | null>;
  address?: FormControl<string | null>;
}> = fb.group<{
  name: FormControl<string | null>;
  address?: FormControl<string | null>;
}>(controls);
```

Today, with fully strict TypeScript settings, the above will not compile:

```
Types of property 'controls' are incompatible.
Type '{ name: FormControl<string | null>; address?: FormControl<FormGroup<SubFormControls> | null | undefined> | undefined; }' is not assignable to type '{ name: FormControl<string | null>; address?: FormGroup<SubFormControls> | undefined; }'.
```

Notice that the `fb.group(...)` is calculating the following type for address: `address?: FormControl<FormGroup<string|null>`. This is clearly wrong -- an extraneous `FormControl` has been added!

This is coming from the calculation of the result type of `fb.group(...)`. In the type definition, if we cannot detect the outer control type, [we assume it's just an unwrapped value, and automatically wrap it in `FormControl`](https://github.com/angular/angular/blob/14.0.0/packages/forms/src/form_builder.ts#L66).

Because the optional `{address?: FormControl<string|null>}` implicitly makes the RHS have type `FormControl<string|null>|undefined`, [the relevant condition is not satisfied](https://github.com/angular/angular/blob/14.0.0/packages/forms/src/form_builder.ts#L55). In particular, the condition expects just `FormGroup<T>`, not `FormGroup<T>|undefined`. So we assume `T` is a value type, and it gets wrapped with `FormControl`.

The solution is to add the cases where `undefined` is included in the union type when detecting which control `T` is (if any).

PR Close #46253
2022-06-06 10:14:19 -07:00
..
BUILD.bazel build: switch devmode output to es2015 (#44505) 2022-01-05 23:20:20 +00:00
directives_spec.ts fix(forms): improve error message for invalid value accessors (#45192) 2022-03-15 13:26:03 -07:00
form_array_spec.ts feat(forms): Implement strict types for the Angular Forms package. (#43834) 2022-04-12 17:37:04 +00:00
form_builder_spec.ts fix(forms): Allow NonNullableFormBuilder to be injected. (#45904) 2022-05-09 17:31:48 -07:00
form_control_spec.ts fix(forms): Add a nonNullable option to FormControl for consistency. 2022-05-19 15:49:02 -07:00
form_group_spec.ts feat(forms): Implement strict types for the Angular Forms package. (#43834) 2022-04-12 17:37:04 +00:00
reactive_integration_spec.ts fix(forms): not picking up disabled state if group is swapped out and disabled (#43499) 2022-03-28 09:26:19 -07:00
template_integration_spec.ts feat(core): triggerEventHandler accept optional eventObj (#45279) 2022-03-09 13:51:54 -08:00
typed_integration_spec.ts fix(forms): allow FormBuilder.group(...) to accept optional fields. (#46253) 2022-06-06 10:14:19 -07:00
util.ts refactor(forms): refactor common validators used in unit tests (#38020) 2020-07-22 20:42:43 -07:00
validators_spec.ts fix(forms): Correct empty validator to handle objects with a property length: 0. (#33729) 2022-02-03 23:15:27 -08:00
value_accessor_integration_spec.ts fix(forms): ensure OnPush ancestors are marked dirty when the promise resolves (#44886) 2022-01-31 21:38:39 +00:00