You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写泛型类型,用FormGroup/FormArray包装TypeScript接口属性?

修正Angular表单泛型类型实现

你的泛型类型错误在于判断逻辑——K extends []是在判断属性名是否为数组,这显然不成立(属性名是字符串,比如phones),正确的做法是判断属性值的类型是否为数组,再分支处理不同的表单控件类型。

步骤1:定义辅助类型

先创建几个辅助类型,用来识别数组、对象类型,以及提取数组元素类型:

// 提取数组的元素类型
type ArrayElement<T> = T extends (infer U)[] ? U : never;

// 判断是否为数组类型
type IsArray<T> = T extends any[] ? true : false;

// 判断是否为非数组的对象类型
type IsObject<T> = T extends object ? T extends any[] ? false : true : false;

步骤2:修正GenericFormModel泛型

结合Angular的表单控件类型,重新编写泛型:

import { FormControl, FormGroup, FormArray } from '@angular/forms';

export type GenericFormModel<T> = {
  [K in keyof T]: 
    IsArray<T[K]> extends true 
      ? FormArray<GenericFormModel<ArrayElement<T[K]>>>
      : IsObject<T[K]> extends true
        ? FormGroup<GenericFormModel<T[K]>>
        : FormControl<T[K] | null>;
};

类型验证

假设Phone接口定义如下:

interface Phone {
  number: string;
  type: string;
}

此时GenericFormModel<Person>会被推导为:

{
  name: FormControl<string | null>;
  age: FormControl<number | null>;
  phones: FormArray<FormGroup<{
    number: FormControl<string | null>;
    type: FormControl<string | null>;
  }>>;
}

完全符合需求:数组属性phones对应FormArray,非数组的基本类型属性对应FormControl,如果是对象类型的属性则对应FormGroup。

内容的提问来源于stack exchange,提问作者matthew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:25:31