1

I'm using the Angular FormBuilder (import { FormBuilder } from '@angular/forms';) to create my FormGroup and inner FormControls as this right now:

formGroup = new FormBuilder().nonNullable.group({
   ...this.newInstance(), // to create all FormControls
});

// Create new instance with default values:
protected override newInstance(): MyDto {
  return {
    id: 0,
    name: '',
    active: true,
    groups: [],
    nodes: [],
  };
}

Where MyDto interface looks like this:

export interface MyDto {
  id: number;
  name: string;
  active: boolean;
  groups: number[];
  nodes: MyNode[];
}

My formGroup now has inner FormControls of the following types:

  • id: FormControl<number> (as expected)
  • name: FormControl<string> (as expected)
  • active: FormControl<boolean> (as expected)
  • groups: FormControl<number> (number instead of number[])
  • nodes: FormControl<MyNode> (MyNode instead of MyNode[])

But if I change my formGroup to this:

formGroup = new FormBuilder().nonNullable.group({
   ...this.newInstance(), // to create all FormControls

   // Correct the arrays...
   groups: [],
   nodes: [],
});

The types are correct: FormControl<number[]> and FormControl<MyNode[]>.

If there any reason why Angular/TypeScript won't be able to recognize my arrays when I use the this.newInstance() with ... spread function? Is there perhaps a better fix than my ugly work-around above? I actually use more arrays in my actual code than the example above, and it's a bit of an eye-sore.

One thing I did try, without any change (as I was kinda expecting), was explicitly mentioning the types in my newInstance function like this:

// Create new instance with default values:
protected override newInstance(): MyDto {
  return {
    id: 0,
    name: '',
    active: true,
    groups: [] as number[],
    nodes: [] as MyNode[],
  } as MyDto;
}

1 Answer 1

0

The typing seems to be lost when we use destructuring.

So we can convert the two properties where typing is lost to be defined with FormControl (Long Syntax), I have used nonNullable property to assert that the typing cannot be null.

Since we have this typing problem I removed the return type of newInstance so that TypeScript type inference can take care of it.

// Create new instance with default values:
protected newInstance() {
  return {
    id: 0,
    name: '',
    active: true,
    groups: new FormControl<number[]>([], {
      nonNullable: true,
    }),
    nodes: new FormControl<number[]>([], {
      nonNullable: true,
    }),
  };
}

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.