Search code examples
angulartypescriptecmascript-6angular-directivecontrolvalueaccessor

TypeError: Class constructor DefaultValueAccessor cannot be invoked without 'new'


There are some Angular third part libraries that provide directives which internally extends the DefaultValueAccessor class.

When they are imported into projects that have their TypeScript compilation target set as es6, they stop working and throw the error:

TypeError: Class constructor DefaultValueAccessor cannot be invoked without 'new'

examples of different libraries affected by this issue:

A workaround would be copy pasting the source code of the library inside my own project (instead of importing the library as an npm dependency). However this is not nice nor very handy to do for obvious reasons.

How to properly solve this issue in the library?


Solution

  • I've resolved by making the class implements ControlValueAccessor instead of extends DefaultValueAccessor.

    As a consequence of that, I also had to implement the missing methods, so I added the following:

    import { ControlValueAccessor } from "@angular/forms";
    // ...
    
    export class MyClass implements ControlValueAccessor {
    
      // ...
    
      onChange = (_: any) => {};
      onTouched = () => {};
    
      // ...
    
      registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
      registerOnTouched(fn: () => void): void { this.onTouched = fn; }
    
      setDisabledState(isDisabled: boolean): void {
        this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
      }
    }
    

    Note that the setDisabledState is not mandatory (the ControlValueAccessor will not force you to implement it, but you need it in order to keep the disabled status of your control working correctly.