Skip to content

fix(forms): fix FormRecord type inference - #50752

Closed
EmmanuelRoux wants to merge 4 commits into
angular:mainfrom
EmmanuelRoux:fix-formrecord-type-inference
Closed

EmmanuelRoux wants to merge 4 commits into
angular:mainfrom
EmmanuelRoux:fix-formrecord-type-inference

Conversation

@EmmanuelRoux

@EmmanuelRoux EmmanuelRoux commented Jun 17, 2023 •

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: #50751

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@pullapprove
pullapprove Bot requested a review from AndrewKushnir June 17, 2023 18:32
@JeanMeche JeanMeche added area: forms forms: Controls API Issues related to AbstractControl, FormControl, FormGroup, FormArray. labels Jun 17, 2023
@ngbot ngbot Bot modified the milestone: Backlog Jun 17, 2023
@EmmanuelRoux
EmmanuelRoux force-pushed the fix-formrecord-type-inference branch from 46d5b75 to 1bd1ae6 Compare June 17, 2023 19:00
Comment thread packages/forms/src/model/form_group.ts Outdated
Updates type inference in `ɵElement` to make `FormRecord` take precedence over `FormGroup`
Add a marker property to `FormRecord` to make its type actually different from `FormGroup`
@EmmanuelRoux
EmmanuelRoux force-pushed the fix-formrecord-type-inference branch from 1bd1ae6 to 961bf32 Compare June 17, 2023 19:07
Comment thread packages/forms/src/model/form_group.ts Outdated
@JeanMeche

Copy link
Copy Markdown
Member

cc @dylhunn You might wanna take a look at this 👍

Add ɵ as prefix to internal property
Comment thread packages/forms/src/model/form_group.ts Outdated
Simplify brand property and avoid value assignment
@AndrewKushnir
AndrewKushnir requested review from dylhunn and removed request for AndrewKushnir June 18, 2023 21:21
@EmmanuelRoux

EmmanuelRoux commented Aug 16, 2023 •

Copy link
Copy Markdown
Contributor Author

Up 🙂 @dylhunn

@dylhunn

dylhunn commented Aug 21, 2023

Copy link
Copy Markdown
Contributor

Interesting. Can you show an example of an inference that would have been broken under the previous regime? It would be good to add it to typed_integration_spec as well, to document the change and prevent regressions.

@EmmanuelRoux

Copy link
Copy Markdown
Contributor Author

@dylhunn you can take a look at the failed test in this PR : #50750

A FormRecord is inferred as FormGroup.
While this is not incorrect technically, because FormRecord actually extends FormGroup (and this is the reason of bad inference), it is probably unexpected.
The helper type ɵElement should probably infer it to FormRecord instead.

@JeanMeche

Copy link
Copy Markdown
Member

@EmmanuelRoux If this PR provides a fix it should also introduce a previously broken test !

@EmmanuelRoux

EmmanuelRoux commented Aug 29, 2023 •

Copy link
Copy Markdown
Contributor Author

@JeanMeche This is why I provided a link to #50750 :

Currently, this does NOT break anything, because FormRecord type is actually compatible with FormGroup (and vice versa). See :

type X = ɵElement<FormRecord<FormControl<string>>, null>;
// X is currently inferred as FormGroup<{[p: string]: FormControl<string>}>

const formGroupX: X = null!;
const formGroupY: FormGroup<{[p: string]: FormControl<string>}> = a; 
const formRecordZ: FormRecord<FormControl<string>> = a; // <-- Currently no error, because FormGroup can be assigned to FormRecord

BUT, if FormRecord would define some specific signature it would become incompatible with FormGroup:

// Let's imagine FormRecord has a new method, for example:
export interface FormRecord<TControl> {
  // ...
  someMethod(): TControl;
}

// Then this would break (as expected) :

const formGroupX: X = null!;
const formGroupY: FormGroup<{[p: string]: FormControl<string>}> = a; 
const formRecordZ: FormRecord<FormControl<string>> = a; // <-- Error, because FormGroup cannot be assigned to FormRecord

This is exactly what the PR #50750 aims to introduce.

@JeanMeche

JeanMeche commented Aug 29, 2023 •

Copy link
Copy Markdown
Member

This is for the sake of commit tree grooming. That we'd like to have tests covering bugfixes / feature introductions.

Either this PR should introduce new test, which shows the fix its bringing or the PR should be merged with #50750.

@EmmanuelRoux

Copy link
Copy Markdown
Contributor Author

@JeanMeche @dylhunn merged with #50750

@EmmanuelRoux

Copy link
Copy Markdown
Contributor Author

Any update on this PR or #50750 please ?

@JeanMeche

Copy link
Copy Markdown
Member

I'll close this in favor of #50750 which is getting reviewed and tested.

@JeanMeche JeanMeche closed this May 17, 2024
@angular-automatic-lock-bot

Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators Jun 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area: forms forms: Controls API Issues related to AbstractControl, FormControl, FormGroup, FormArray.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants