Angular:FormArray.at()返回AbstractControl而非FormControl的疑问
Angular FormArray.at() 返回AbstractControl的原因及无强制类型转换的解决方案
为什么返回AbstractControl?
FormArray是Angular表单的控件集合容器,设计上支持存储任意AbstractControl的子类(包括FormControl、FormGroup、嵌套FormArray)。为了保证API的通用性——不管后续往数组里添加什么类型的控件都能兼容,它的at()方法默认返回最顶层的AbstractControl类型。
哪怕初始化时只放了FormControl,TypeScript也没法在编译期保证后续不会添加其他类型控件,所以不会自动把返回值推断为FormControl。
无需强制类型转换的正确实现方式
方法1:给FormArray指定泛型类型(最推荐)
创建FormArray时直接声明它存储的是FormControl类型,at()方法会自动返回对应具体类型:
import { FormControl, FormArray } from '@angular/forms'; // 组件类内部 this.formArray = new FormArray<FormControl<string>>([ new FormControl(''), new FormControl(''), ]); // 用getter替代方法,更符合Angular组件实践 get formControlA() { return this.formArray.at(0); } get formControlB() { return this.formArray.at(1); }
模板代码修正(补全原代码的语法错误):
<mat-select [formControl]="formControlA">...</mat-select> <mat-select [formControl]="formControlB">...</mat-select>
方法2:使用类型守卫做运行时校验
如果需要更严谨的类型校验(防止后续误改控件类型),可以写一个类型守卫函数,同时在编译期和运行时确保返回的是FormControl:
import { AbstractControl, FormControl } from '@angular/forms'; // 类型守卫函数 private isFormControl(control: AbstractControl): control is FormControl { return control instanceof FormControl; } get formControlA() { const control = this.formArray.at(0); if (!this.isFormControl(control)) { throw new Error('控件类型错误:期望是FormControl'); } return control; } get formControlB() { const control = this.formArray.at(1); if (!this.isFormControl(control)) { throw new Error('控件类型错误:期望是FormControl'); } return control; }
这种方式既避免了强制类型转换,又能在代码出错时及时抛出明确的错误提示。
内容的提问来源于stack exchange,提问作者patrick
相关产品推荐
相关产品推荐

