Angular中如何正确为FormArray声明类型?
如何正确声明表单相关类型?
假设我有一个FormGroup:
- 我在构造函数中初始化它:
export interface MyType { myValue: string }
myForm: FormGroup myArray: FormArray // <FormControl<MyType>> constructor(private _formBuilder: FormBuilder) { myForm = new FormGroup({ myArray: this._formBuilder.array([]) }) }
- 我有一个按钮用来向数组中添加新元素,实现如下:
addElement() { this.myArray = this.myForm.get('myArray') as unknown as FormArray this.myArray.push(this.newElement()) } private _newElement(): FormGroup { // 应该使用什么类型? return this._formBuilder.group({ myValue: '' }) }
当我尝试这样声明myArray时:
myArray: FormArray<FormControl<MyType>>
出现了如下错误:
Argument of type 'FormGroup<any>' is not assignable to parameter of type 'FormControl<MyType>'. Type 'FormGroup<any>' is missing the following properties from type 'FormControl<MyType>': defaultValue, registerOnChange, registerOnDisabledChange
想请教两个问题:
private _newElement(): FormGroup { // 应该使用什么类型?这里应该用什么类型?myArray: FormArray<FormControl<MyType>>这样声明是否正确?注:FormGroup<FormControl<MyType>>是错误的
问题1:_newElement的返回类型
你的_newElement返回的是对应MyType的表单组,应该声明为FormGroup<{ myValue: FormControl<string> }>——因为MyType里的myValue是string类型,对应的表单控件是FormControl<string>。
修改后的代码:
private _newElement(): FormGroup<{ myValue: FormControl<string> }> { return this._formBuilder.group({ myValue: new FormControl('', { nonNullable: true }) // 可根据需求设置初始值和验证器 }) }
如果想更贴合MyType结构,也可以先定义一个表单类型复用:
type MyTypeForm = { [K in keyof MyType]: FormControl<MyType[K]> } // 此时_newElement的返回类型为FormGroup<MyTypeForm> private _newElement(): FormGroup<MyTypeForm> { return this._formBuilder.group({ myValue: '' }) as FormGroup<MyTypeForm> }
问题2:myArray的声明是否正确
当前声明FormArray<FormControl<MyType>>是错误的——因为你往数组里push的是FormGroup,而非FormControl。正确的声明应该匹配数组元素的类型:
如果用第一种方式:
myArray: FormArray<FormGroup<{ myValue: FormControl<string> }>>;
如果用自定义的MyTypeForm:
myArray: FormArray<FormGroup<MyTypeForm>>;
同时,在addElement中获取表单数组时,也可以更精准地断言类型,避免unknown:
addElement() { this.myArray = this.myForm.get('myArray') as FormArray<FormGroup<MyTypeForm>>; this.myArray.push(this._newElement()); }
另外,构造函数初始化myForm时,也可以指定完整类型,减少后续断言操作:
myForm: FormGroup<{ myArray: FormArray<FormGroup<MyTypeForm>> }>; constructor(private _formBuilder: FormBuilder) { this.myForm = new FormGroup({ myArray: this._formBuilder.array([]) }) as FormGroup<{ myArray: FormArray<FormGroup<MyTypeForm>> }>; }
这样就能解决类型不匹配的错误,同时获得完整的TypeScript类型提示。
内容的提问来源于stack exchange,提问作者Raphaël Balet
相关产品推荐
相关产品推荐

