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

Invalid type provided for FormArray #511

Open
mopcweb opened this issue Aug 5, 2021 · 2 comments
Open

Invalid type provided for FormArray #511

mopcweb opened this issue Aug 5, 2021 · 2 comments

Comments

@mopcweb
Copy link

mopcweb commented Aug 5, 2021

Describe the bug

There is invalid types provided in case of formArray as part of formGroup

Expected Behavior

Types should be correct.
This could be achieved by using conditional types.

To Reproduce

import { FormBuilder, AbstractControl } from '@angular/forms';
import { IFormBuilder, IFormGroup, IFormArray } from '@rxweb/types';

interface IUser {
  name: string;
  hobbies: IFormArray<IHobby>; // Same incorrect behaviour for hobbies: IHobby[];
}

interface IHobby {
  title: string;
}

@Compoent({  })
class SomeComponent {
  public form: IFormGroup<IUser>;
  
  private readonly _formBuilder: IFormBuilder
  
  constructor(
    _formBuilder: FormBuilder,
  ) { this._formBuilder = _formBuilder; }
  
  public ngOnInit(): void {
    this._initForm();
  }
  
  private _initForm(initialData: Partial<IUser> = { }): void {
    this.form = this._formBuilder.group<IUser>({
      name: [initialData.name],
      hobbies: this._formBuilder.array(initialData?.hobbies ?? []), // Same if initialData.hobbies.map((item) => this._formBuilder.group({ ... }))
    })
  
    this.form.controls.hobbies.controls // In runtime here we have list of controls of this FormArray
    // But in compile time we have TypeError by TS - there is no `controls` property as it is of type IAbstractControl
  }
}

Fix

use condition types in i-form-group.ts

export interface IFormGroup<T> extends IAbstractControl<T, T> {
  controls: {
    // [key in keyof T]: IAbstractControl<T[key], T>; // Change this
    [key in keyof T]: T[key] extends IFormArray<any> ? T[key] : IAbstractControl<T[key], T>; // To this
  };
  ...,
}

Url (stackblitz or plunker or other)

Package Version

@rxweb/[email protected]

@mopcweb
Copy link
Author

mopcweb commented Aug 5, 2021

Update

same situation is for IFormArray w/ formGroups in it (same example):

interface IUser {
  name: string;
  hobbies: IFormArray<IHobby>; // Same incorrect behaviour for hobbies: IHobby[];
}

@Compoent({  })
class SomeComponent {
  // ...

  private _initForm(initialData: Partial<IUser> = { }): void {
    const hobbiesFormGroups = (initialData?.hobbies ?? []).map((hobby) => this._formBuilder.group<IHobby>({
      title: [hobby.title],
    }))

    this.form = this._formBuilder.group<IUser>({
      name: [initialData.name],
      hobbies: this._formBuilder.array(hobbiesFormGroups),
    })
  
    this.form.controls.hobbies.controls[0].controls // In runtime here we have controls for first hobby in array
    // But in compile time we have TypeError by TS - there is no `controls` property as it is of type IAbstractControl
  }
}

fix:

export interface IFormArray<Item> extends IAbstractControl<Item[]> {
  controls: Item extends IAbstractControl<any> ? Item[] : Array<IAbstractControl<Item>>;
  ...
}

in this case we'll need to cast formBuilder type manually

class SomeComponent {
  private readonly _formBuilder: IFormBuilder;
  constructor(
    _formBuilder: FormBuilder,
  ) { this._formBuilder = _formBuilder as IFormBuilder; }
}

@ajayojha
Copy link
Member

@mopcweb I really appreciate the suggested solution for the issue :).

I think we should explore other possibilities to fix this issue because if we add this solution then existing package users will face project build issues. I wish to avoid the same. if you have any other solution to overcome the build issue then please share the same.

I will also explore the possibilities to fix this issue without build failures for the existing users.

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

No branches or pull requests

2 participants