Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fb.array doesn't transfer the generic type Control to the FormArray construction #137

Closed
jogelin opened this issue Jan 11, 2022 · 7 comments

Comments

@jogelin
Copy link

jogelin commented Jan 11, 2022

return new FormArray<T>(controls, validatorOrOpts, asyncValidator);

  array<T, Control extends AbstractControl = T extends Record<any, any> ? FormGroup<ControlsOf<T>> : FormControl<T>>(
    controlsConfig: Control[],
    validatorOrOpts?: ConstructorParameters<typeof FormArray>[1],
    asyncValidator?: ConstructorParameters<typeof FormArray>[2]) {
    const controls = controlsConfig.map(c => (this as any)._createControl(c));

    return new FormArray<T, Control>(controls, validatorOrOpts, asyncValidator); // <-- here the Control should be provided
  }
@NetanelBasal
Copy link
Member

I'm not sure I follow.

@jogelin
Copy link
Author

jogelin commented Jan 11, 2022

Sorry I encoded it a bit fast. Below are some details

First, you can find an example here: https://stackblitz.com/edit/angular-ivy-ktpmpb

The issue is that when we specify a Control type in a FormArray generic type (FormArray<T, Control>), the FormBuilder.array return a wrong type because it decides what will be the Control type based on

array<T, Control extends AbstractControl = T extends Record<any, any> ? FormGroup<ControlsOf<T>> : FormControl<T>>(controlsConfig: Control[], validatorOrOpts?: ConstructorParameters<typeof FormArray>[1], asyncValidator?: ConstructorParameters<typeof FormArray>[2]): FormArray<T, T extends Record<any, any> ? FormGroup<ControlsOf<T>> : FormControl<T>>;

In my use case, I decided to specify a FormControl as the Control type of my FormArray: FormArray<UserAddress, FormControl<UserAddress>> but the return value will not take into account my control type and use the dynamic type which is FormArray<UserAddress, FormGroup<ControlsOf<UserAddress>>>.

To fix this, I think we should put the Control type in the FormArray in the FormBuild like:

  array<T, Control extends AbstractControl = T extends Record<any, any> ? FormGroup<ControlsOf<T>> : FormControl<T>>(
 ...
    // CURRENT
    return new FormArray<T>(controls, validatorOrOpts, asyncValidator); // <-- here the Control should be provided
    
    // FIX
    return new FormArray<T, Control>(controls, validatorOrOpts, asyncValidator); // <-- here the Control should be provided
  }

@NetanelBasal
Copy link
Member

Can you please try it locally in the repo playground/spec?

@jogelin
Copy link
Author

jogelin commented Jan 11, 2022

Issue related:

ValuesOf does not work when we specify a Control type in a FormArray.

here is an example based on the previous comment: https://stackblitz.com/edit/angular-ivy-w1eyiv?file=src%2Fapp%2Fapp.component.ts

So to solve my previous issue, instead of using a FormBuilder I can use new FormArray([]).

However, the ValuesOf<UserForm> doesn't match my FormArray type because I specified the Control generic type.

So NonUndefined<T[K]> extends FormArray<infer R> doesn't not match FormArray<UserAddress, FormControl<UserAdress>

But it works if I just put FormArray<UserAddress>. But Then I come back to the first issue where a FormGroup is used instead of a FormControl

jogelin pushed a commit to jogelin/reactive-forms that referenced this issue Jan 11, 2022
@jogelin
Copy link
Author

jogelin commented Jan 11, 2022

Can you please try it locally in the repo playground/spec?

As requested, same issue in your repo playground: https://github.com/jogelin/reactive-forms/tree/issue-137

@NetanelBasal
Copy link
Member

I mean after your fix :)

@jogelin
Copy link
Author

jogelin commented Jan 11, 2022

I created a PR with both fixes + some playground improvements to validate my fixes.

#138

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants