angular/packages/core/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
..
acceptance refactor(core): add helpful info in the pipe not found error message (#46247) 2022-06-06 10:13:28 -07:00
animation fix(animations): apply default params when resolved value is null or undefined (#45339) 2022-03-17 14:02:37 -07:00
bundling fix(forms): allow FormBuilder.group(...) to accept optional fields. (#46253) 2022-06-06 10:14:19 -07:00
change_detection refactor(core): remove duplicated code in change_detection_util (#45599) 2022-04-12 22:26:09 +00:00
compiler build: enable useUnknownInCatchVariables (#44679) 2022-02-01 18:17:29 +00:00
debug feat(core): triggerEventHandler accept optional eventObj (#45279) 2022-03-09 13:51:54 -08:00
di refactor(core): rename INJECTOR_INITIALIZER -> ENVIRONMENT_INITIALIZER (#45845) 2022-05-02 15:02:06 -07:00
dom test: clean up internal testing utilities (#42177) 2021-05-26 20:07:25 +00:00
i18n build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
linker fix(core): better error message when directive extends a component (#45658) 2022-04-18 09:24:23 -07:00
metadata build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
reflection refactor(core): remove unused logic from reflection capabilities (#45335) 2022-03-24 11:02:39 -07:00
render3 refactor(core): remove ManualOnPush change detection (#45943) 2022-05-10 09:37:07 -07:00
sanitization refactor(core): make the error messages tree shakable (#44359) 2022-01-18 17:38:10 -08:00
strict_types refactor(core): rename ...WithMeta types to ...Declaration and alias to unknown (#41119) 2021-03-22 08:57:18 -07:00
testability test(core): reset Testability getter after each test (#45947) 2022-05-10 16:02:53 -07:00
util refactor(core): remove duplicated code in change_detection_util (#45599) 2022-04-12 22:26:09 +00:00
zone test: clean up internal testing utilities (#42177) 2021-05-26 20:07:25 +00:00
application_init_spec.ts test(core): refactor ApplicationInitStatus tests to avoid TestBed side-effects (#33222) 2021-02-22 08:41:49 -08:00
application_module_spec.ts test(core): fix a crosstalk issue with locale ids (#45626) 2022-04-18 09:28:42 -07:00
application_ref_integration_spec.ts refactor: delete the View Engine runtime (#43884) 2021-11-23 21:10:06 +00:00
application_ref_spec.ts refactor(compiler-cli): reorganize importProvidersFrom to avoid cycles (#45687) 2022-04-20 16:01:55 -07:00
BUILD.bazel build: switch devmode output to es2015 (#44505) 2022-01-05 23:20:20 +00:00
component_fixture_spec.ts feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
dev_mode_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
directive_lifecycle_integration_spec.ts build: bundle spec files for saucelabs legacy job (#44281) 2021-11-30 11:56:04 -05:00
error_handler_spec.ts refactor(core): remove unused error handler logic (#46216) 2022-06-02 13:40:16 -07:00
event_emitter_spec.ts test: clean up internal testing utilities (#42177) 2021-05-26 20:07:25 +00:00
fake_async_spec.ts test: clean up internal testing utilities (#42177) 2021-05-26 20:07:25 +00:00
forward_ref_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
runtime_error_spec.ts refactor(core): split RuntimeError unit test up (#46239) 2022-06-06 10:12:06 -07:00
test_bed_spec.ts fix(core): handle AOT-compiled standalone components in TestBed correctly (#46052) 2022-05-23 09:25:08 -07:00
util_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00