Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

[flow] Improve covariant style #3172

Description

@jasonLaster

We currently follow an awkward style for covariants

  constructor() {
    super();

    const self: any = this;
    self.closeConditionalPanel = this.closeConditionalPanel.bind(this);
    self.onEscape = this.onEscape.bind(this);
    self.onGutterClick = this.onGutterClick.bind(this);
    self.onGutterContextMenu = this.onGutterContextMenu.bind(this);
    self.onScroll = this.onScroll.bind(this);
    self.onSearchAgain = this.onSearchAgain.bind(t

@thejameskyle shared some wisdom on how we can improve the style


Class methods are covariant in Flow by default, which in effect means they are "read-only" and cannot be assigned to.

class Error extends React.Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this); // Error
    //   ^ property `onClick`. Covariant property `onClick` incompatible with contravariant use in
    //     assignment of property `onClick`
  }
  
  onClick(event: ButtonClickEvent) {
    // ...
  }
  
  render() {
    return <button onClick={this.onClick}>Click Me</button>;
  }
}

In order to make this work, you need to use an additional class field, which are invariant (read & write) by default, like this:

class WorksWithClassPropertyType extends React.Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this); // Works!
  }
  
  onClick: (ButtonClickEvent) => void;
  onClick(event) {
    // ...
  }
}

Alternatively you can use the class properties proposal to get around all of this:

class WorksWithClassPropertyArrowFunction extends React.Component {
  onClick = (event: ButtonClickEvent) => {
    // ...
  };
}

[See in Try Flow]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    Priority

    None yet

    Jira

    None yet

    Severity

    None yet

    Estimate

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions