Angular中FormGroup作为@Input传递时类型断言失效问题
Angular Typed Forms 跨组件传递时保留类型信息的方案
我在多个组件中使用formBuilder创建带类型的FormGroup(Typed Forms),但将创建好的FormGroup通过@Input传递给子组件时,类型断言没有生效,想知道除了手动定义接口之外,还有哪些方式可以获取FormControl的类型。
父组件代码
TypeScript
public form1 = this.formBuilder.group({ name: ["", Validators.required], enabled: [false, Validators.required] }); public form2 = this.formBuilder.group({ date: ["", Validators.required] }); public form3 = this.formBuilder.group({ data: ["", Validators.required], recurring: [true, Validators.required] }); public form = this.formBuilder.group({ form1: this.form1, form2: this.form2, form3: this.form3, });
HTML
<child1 [form1]="form1"></child1> <child2 [form2]="form2"></child2> <child3 [form3]="form3"></child3>
子组件代码
TypeScript
@Input() form1: FormGroup;
HTML
<form [formGroup]="form1"> <input type="text" formControlName="name" /> </form>
已知的接口定义方式
我知道可以为每个FormGroup单独定义接口,在子组件中使用:
interface Form1 { name: FormControl<string>; enabled: FormControl<boolean>; } form: FormGroup<Form1> = new FormGroup({ name: new FormControl(""), enabled: new FormControl(false) })
其他实现方案
1. 利用typeof直接提取父组件表单类型
在父组件中导出已创建表单的类型,子组件直接引用即可自动继承完整类型信息:
父组件
// 导出表单实例的类型 export type Form1Type = typeof form1; export type Form2Type = typeof form2; export type Form3Type = typeof form3;
子组件
import { Form1Type } from '../parent.component'; @Input() form1: Form1Type;
2. 结合ReturnType提取函数创建的表单类型
如果表单通过函数封装创建逻辑,可通过ReturnType自动推导返回的FormGroup类型:
父组件
private createForm1() { return this.formBuilder.group({ name: ["", Validators.required], enabled: [false, Validators.required] }); } public form1 = this.createForm1(); // 导出函数返回值的类型 export type Form1Type = ReturnType<typeof this.createForm1>;
子组件
import { Form1Type } from '../parent.component'; @Input() form1: Form1Type;
3. 通过表单值类型反向生成FormGroup泛型
若仅需约束表单值结构,可先提取值类型,再映射为FormGroup的泛型定义:
父组件
// 提取表单值的类型 export type Form1Value = typeof form1.value;
子组件
import { Form1Value } from '../parent.component'; import { FormGroup, FormControl } from '@angular/forms'; @Input() form1: FormGroup<{ [K in keyof Form1Value]: FormControl<Form1Value[K]> }>;
内容的提问来源于stack exchange,提问作者tangel
相关产品推荐
相关产品推荐

