Skip to content

angular/forms and StrictFunctionTypes in TypeScript #25824

@rkirov

Description

@rkirov

@kara and I looked into some real-world errors of users of forms API with TS strictFunctionTypes.

This issue records the current status, recommended workarounds and future direction for improvements.

The core issue is that ValidatorFn takes an AbstractControl, often people provide validations functions that can only accept a subtype like FormControl.

We experimented with some improved typing on the framework side along the lines of this pattern.

type ValidatorFn<T=Base> = (c: T) => void;

abstract class Base {
  a = '';
  cl?: ValidatorFn<this>;
  constructor(cl?: ValidatorFn) {
    this.cl = cl;
  }
  setValidator(cl: ValidatorFn<this>) {
    this.cl = cl;
  }
}

class D extends Base  {
  constructor(cl?: ValidatorFn<D>) {
    super(cl as any);  // not good, but needed :(
  }
  b = '';
}

let d = new D((d: D) => {});
d.setValidator((d: D) => {});

But ultimately decided it is would not be worth the effort to fix on the frameworks side at this point. The recommended solution is to simply write all validator functions as consuming AbstractControls, and downcast when needed:

let validator: ValidatorFn = function(c: AbstractControl) {
  let group = c as FormGroup; 
}

or the safer variant

let validator: ValidatorFn = function(c: AbstractControl) {
  if (c instanceof FormGroup) {
    // c is FormGroup here.
  }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions