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

Angular自定义ValidatorFn时AbstractControl不存在controls属性如何解决

问题原因

AbstractControl 是 Angular 表单中 FormGroup、FormControl、FormArray 的公共基类,本身未定义 controls 属性,该属性仅存在于 FormGroup 和 FormArray 子类中,因此直接在 AbstractControl 类型的变量上调用 controls 会触发类型报错。


解决方法

方法1:类型断言(推荐,场景确定时使用)

如果你可以确保该验证器只会绑定到 FormGroup 类型的表单上,直接将入参断言为 FormGroup 即可解决报错,代码修改如下:

import { FormGroup, ValidatorFn, AbstractControl } from '@angular/forms';
export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
  return function validate (formGroup: AbstractControl) {
    let checked = 0;
    // 类型断言为FormGroup
    const targetGroup = formGroup as FormGroup;

    Object.keys(targetGroup.controls).forEach(key => {
      const control = targetGroup.controls[key];

      if (control.value === true) {
        checked ++;
      }
    });

    if (checked < minRequired) {
      return {
        requireOneCheckboxToBeChecked: true,
      };
    }

    return null;
  };
}

该方法实现简单,无额外运行时开销,符合绝大多数自定义表单组验证器的使用场景。

方法2:类型守卫(更严谨,兼容不确定场景)

如果存在验证器被误绑定到非FormGroup类型控件的可能,可以添加运行时类型判断,避免报错同时保证代码健壮性:

import { FormGroup, ValidatorFn, AbstractControl } from '@angular/forms';
export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
  return function validate (formGroup: AbstractControl) {
    // 非FormGroup类型直接跳过验证
    if (!(formGroup instanceof FormGroup)) {
      return null;
    }
    let checked = 0;

    Object.keys(formGroup.controls).forEach(key => {
      const control = formGroup.controls[key];

      if (control.value === true) {
        checked ++;
      }
    });

    if (checked < minRequired) {
      return {
        requireOneCheckboxToBeChecked: true,
      };
    }

    return null;
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:57:01