Problem description
From the documentation we see two different lines with the group()
function
group(controlsConfig: { [key: string]: any; }, options?: AbstractControlOptions): FormGroup
AND
group(controlsConfig: { [key: string]: any; }, options: { [key: string]: any; }): FormGroup
The 2nd definition is what is deprecated
The difference in this lines is options?: AbstractControlOptions
and options: { [key: string]: any; }
To understand why angular is throwing this error we will now consider AbstractControlOptions
interface AbstractControlOptions {
validators?: ValidatorFn | ValidatorFn[] | null
asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null
updateOn?: 'change' | 'blur' | 'submit'
}
We continue to breakdown the problem by noting that the difference between this structure and your structure is ValidatorFn[]
interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null
}
Overally, the error is thrown in your case because your Validator
function is expected to take a control and return ValidationErrors | null
. In the line validate(control: AbstractControl): void
, your code actually returns void
but expected to return a ValidationError | null
Solution
From the problem description, the solution is to simply modify the ValidatorFn
Ensure that your ValidatorFn
returns a ValidationError
or if no error returns null
From ValidationErrors defination
type ValidationErrors = {
[key: string]: any;
};
You will need to return a key value pair object e.g {required_if: true}
We can change your code by adding return statements as expected
class ValidateThirdNumber {
static validate(control: AbstractControl): ValidationErrors | null {
if (control) {
const isMultiFlavor = control.get('isMultiFlavor')?.value;
const ingredientFlavor = control.get('ingredientFlavor')?.value;
const ingredientBrand = control.get('ingredientBrand')?.value;
const ingredientName = control.get('ingredientName')?.value;
if (isMultiFlavor && ingredientFlavor.trim().length === 0) {
control.get('ingredientFlavor')?.setErrors({required_if: true});
return ({required_if: true});
} else {
control.get('ingredientFlavor')?.setErrors(null);
}
if (!ingredientFlavor && !ingredientBrand && !ingredientName) {
control.get('ingredientName')?.setErrors({required_at_least: true});
control.get('ingredientFlavor')?.setErrors({required_at_least: true});
control.get('ingredientBrand')?.setErrors({required_at_least: true});
return ({required_at_least: true});
} else {
control.get('ingredientName')?.setErrors(null);
control.get('ingredientFlavor')?.setErrors(null);
control.get('ingredientBrand')?.setErrors(null);
}
if (ingredientBrand && ingredientName && ingredientName === ingredientBrand) {
control.get('ingredientName')?.setErrors({not_the_same: true});
control.get('ingredientBrand')?.setErrors({not_the_same: true});
return ({not_the_same: true});
}
}
return null;
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…