'How can I cast an AbstractControl to a FormControl in a template?
I have a FormGroup that I'm passing from a parent component to a child, and then within that FormGroup there's a control that I'm passing from the first child to a second child. However I then want to use the control in a button so that I can alter the state of the formgroup using it.
However when I do form.get('controlName'), it returns an AbstractControl, and when I try to pass the AbstractControl to the [formControl] directive of the button I get an error saying that Type AbstractControl is not assignable to abstract control.
Usually I'd just cast the control to a FormControl in my component but this won't work as I'm using the control directly in the template.
The form
this.form = this._formBuilder.group({
      cost: this._formBuilder.control(''),
      width: this._formBuilder.control('')
    })
First child template
<app-form-subsection-cost [subsectionFormControl]="form.get('cost')"></app-form-subsection-cost>
Second child
export class FormSubsectionCostComponent implements OnInit {
  @Input() subsectionFormControl: AbstractControl;
  constructor() { }
  ngOnInit(): void {
  }
}
Second child template
<button [formControl]="subsectionFormControl as FormControl" value="Yes">Yes</button> //Error on formControl directive
I can't do this:
<app-form-subsection-cost [subsectionFormControl]="form.get('cost')"
[subsectionFormControl]="form.get('cost') as FormControl"></app-form-subsection-cost>
Solution 1:[1]
What I do is define a method in my component to return the FormControl with a given name.
  fc(name) { return this.form.get(name) as FormControl; }
Then use it in the template:
  [formControl]="fc('subsectionFormControl')
Solution 2:[2]
You can write a method like Thor suggested, but unfortunately the best supported out-of-the-box solution I have found is to use the $any() cast function. This is less safe, but you don't have to add a cast function to every affected component.
Solution 3:[3]
For what it's worth: define setter / getter, and allow superclass on setter:
@Input() 
set control(control: AbstractControl) {
    this._control = control as FormControl;
}
get control(): FormControl {
    return this._control;
}
If there's a chance the cast in the setter will backfire, do a typeof + throw Error beforehand to fail-fast.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Thor | 
| Solution 2 | Coderer | 
| Solution 3 | Simon | 
