angularangular-reactive-formsangular-validationangular15

error TS2769: No overload matches this call Overload 1 of 5, '(value: string | FormControlState<string>, opts: FormControlOptions


I am learning Angular. I follow the example at

https://www.angulartraining.com/daily-newsletter/rxjs-debouncetime-operator/

https://stackblitz.com/edit/at-debouncetime?file=app%2Fcreditcardvalidator.directive.ts,app%2Fapp.component.html,app%2Fapp.component.ts

which is ok at version 5.0.0. However, compiling it with version 15.1.0 get the following errors. How to fix it?

Error: src/app/app.component.ts:16:5 - error TS2769: No overload matches this call.
  Overload 1 of 5, '(value: string | FormControlState<string>, opts: FormControlOptions & { nonNullable: true; }): FormControl<string>', gave the following error.
    Argument of type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to parameter of type 'FormControlOptions & { nonNullable: true; }'.
      Type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to type '{ nonNullable: true; }'.
  Overload 2 of 5, '(value: string | FormControlState<string>, opts: FormControlOptions & { initialValueIsDefault: true; }): FormControl<string>', gave the following error.
    Argument of type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to parameter of type 'FormControlOptions & { initialValueIsDefault: true; }'.
      Type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to type '{ initialValueIsDefault: true; }'.
  Overload 3 of 5, '(value: string | FormControlState<string>, validatorOrOpts?: ValidatorFn | ValidatorFn[] | FormControlOptions | null | undefined, asyncValidator?: AsyncValidatorFn | ... 2 more ... | undefined): FormControl<...>', gave the following error.
    Argument of type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to parameter of type 'ValidatorFn | ValidatorFn[] | FormControlOptions | null | undefined'.
      Type '(control: FormControl<any>) => ValidationErrors | null' is not assignable to type 'ValidatorFn'.
        Types of parameters 'control' and 'control' are incompatible.
          Type 'AbstractControl<any, any>' is missing the following properties from type 'FormControl<any>': defaultValue, registerOnChange, registerOnDisabledChange

16     CreditCardValidator.validateCcNumber
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  src/app/app.component.ts:16:5
    16     CreditCardValidator.validateCcNumber
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Did you mean to call this expression?

Solution

  • Solution 1: Cast as ValidatorFn

    cardControl: FormControl = new FormControl(
      '',
      CreditCardValidator.validateCcNumber as ValidatorFn
    );
    

    Solution 2: Migrate the validateCcNumber to return as ValidatorFn

    static validateCcNumber(): ValidatorFn {
      return (control: AbstractControl): ValidationErrors | null => {
    
        // Implementation
        if (
          !(
            control.value.startsWith('37') ||
            control.value.startsWith('4') ||
            control.value.startsWith('5')
          )
        ) {
          // Return error if card is not Amex, Visa or Mastercard
          return {
            creditCard:
              'Your credit card number is not from a supported credit card provider',
          };
        } else if (control.value.length !== 16) {
          console.log(control.value);
          // Return error if length is not 16 digits
          return { creditCard: 'A credit card number must be 16-digit long' };
        }
        // If no error, return null
        return null;
      };
    }
    
    cardControl: FormControl = new FormControl(
      '',
      CreditCardValidator.validateCcNumber()
    );
    

    Demo @ StackBlitz