Angular 14带类型FormControl:如何递归继承复杂接口类型?
适配嵌套结构的Angular带类型表单控件类型转换方案
可以通过递归类型判断+条件分支修改你的AsFormControls类型,让它自动识别嵌套对象并对应生成FormGroup,同时保留对基础类型的FormControl映射。
核心实现代码
首先定义辅助类型判断目标属性是否为需要嵌套的对象,再实现递归转换的主类型:
import { FormControl, FormGroup, FormArray } from '@angular/forms'; // 辅助类型:判断是否为需要转FormGroup的嵌套对象(排除Date、数组、null/undefined等特殊类型) type IsNestedObject<T> = T extends object ? T extends Date | Array<any> | null | undefined ? false : true : false; // 辅助类型:判断是否为需要转FormArray的数组类型 type IsFormArray<T> = T extends Array<any> ? true : false; // 递归转换类型:支持嵌套对象、数组和基础类型 export type AsFormControls<T> = { [K in keyof T]: IsFormArray<T[K]> extends true ? FormArray<FormControl<T[K][number]>> : IsNestedObject<T[K]> extends true ? FormGroup<AsFormControls<T[K]>> : FormControl<T[K]>; };
使用示例
针对你的嵌套接口INotSoSimple,可以直接像一级结构一样声明表单:
interface INotSoSimple { d: { e: string; f: Date; } } // 组件中声明表单 form: FormGroup<AsFormControls<INotSoSimple>>;
此时form.controls.d会被自动推断为FormGroup<AsFormControls<{e: string; f: Date}>>,完全匹配嵌套结构的类型校验。
思路拆解
- 类型分支判断:通过两个辅助类型区分三种场景:
- 数组类型:映射为
FormArray,内部元素对应FormControl - 纯嵌套对象:递归调用
AsFormControls生成对应的FormGroup - 基础类型/特殊对象(Date、null/undefined):直接映射为
FormControl
- 数组类型:映射为
- 递归处理嵌套:遇到嵌套对象时,对其内部属性再次执行
AsFormControls转换,实现多层嵌套的自动适配 - 边界场景兼容:提前排除Date、数组等不需要转FormGroup的对象类型,避免错误映射
扩展说明
如果你的业务中还有其他特殊类型需要自定义映射(比如自定义类),可以修改IsNestedObject的判断逻辑,添加对应的排除条件即可。
内容的提问来源于stack exchange,提问作者Bruno Wermelinger Barcellos
相关产品推荐
相关产品推荐

