Flow: Class bind method in constructor

Created on 28 Mar 2018  路  4Comments  路  Source: facebook/flow

I am unable to bind methods in a class's constructor without flow giving a because property X is not writable. error. Please advise what I'm doing wrong here.

Thank you!

https://flow.org/try/#0PTAEAEDMBsHsHcBQiDG0CGBnToCiAPdAWwAdoBTUAb0VFEwBd0HyAuUSdaTcgbmTopYAO0YAnAK4oGsMQAoAlNVp1QDABYBLTADpGzSgF4OXHvxV0N2nS0abhAc1DGru2w3sOdAI3sATOVcFfjoAXwE1cjtHRWVVUDFyBgkxYTUtXX0WENBw8KA

Most helpful comment

I think if you want to do the binding that way, you will need to put a type for the method.

flow.org/try

// @flow

class Example {
  state: false;
  testing: () => boolean;

  constructor() {
    this.state = false;
    this.testing = this.testing.bind(this);
  }

  testing() {
    return this.state;
  }
}

Or something similar based on what the type of this.state is.

All 4 comments

I think if you want to do the binding that way, you will need to put a type for the method.

flow.org/try

// @flow

class Example {
  state: false;
  testing: () => boolean;

  constructor() {
    this.state = false;
    this.testing = this.testing.bind(this);
  }

  testing() {
    return this.state;
  }
}

Or something similar based on what the type of this.state is.

Thank you for the quick response! Is there a better/recommended way to do the binding?

Personally, I like using the class properties proposal. Essentially, this lets you set values to properties of a class without the need of a constructor. However, this feature doesn't exist in JS yet so you will need to use babel-plugin-transform-class-properties (or @babel/plugin-proposal-class-properties if you're on Babel v7).

The properties can also be functions/arrow functions, and because arrow functions keep the original value of this, you don't have to do any binding.

So this:

// @flow

class Example {
  state: boolean;
  testing: () => boolean;

  constructor() {
    this.state = false;
    this.testing = this.testing.bind(this);
  }

  testing() {
    return this.state;
  }

  otherMethod() {
    // Do stuff
  }
}

could be simplified to this:

// @flow

class Example {
  state: boolean = false;

  testing = () => {
    return this.state;
  };

  otherMethod() {
    // Do stuff
  }
}

So basically any method that needs to be bound, you can just change into the arrow syntax.

Thanks again @saadq!

For personal future reference: https://flow.org/try/#0PTAEAEDMBsHsHcBQiSgPIAcAuBLWA7UARmQGNoBDAZytAGELSALAU1AG9FRQqsKsWALlCQK0KiwDcybqQK8ATgFdSWWAoAUASg5duoLExxUAdL35sAvCLETpe7hsPHhFfAE8tJgbxz4A5qDWzqY+uAEmAEZ+ACZORlRa0twAvjIGLL4B2rr6oAosWEoKhCFmfALJoGlpyKiYuASgAExklDT0jKzNuTwVQjbiUuly+Ioqapo6nHll5gJBg3bp3GVhfoHBCd6Z4f5RsfHGSXq1q7sbizmWAHy93AVFJQbb88OpiLUsAB4Y6lgcTrMNgpaRAA

// @flow

// Option 1

class Cache {
  state: false;

  constructor() {
    this.state = false;

    (this: any).testing = this.testing.bind(this);
  }

  testing() {
    return this.state;
  }
}


// Option 2

class Cache2 {
  state: false;

  constructor() {
    this.state = false;

    this.testing = this.testing.bind(this);
  }

  testing = () => {
    return this.state;
  }
}

export { Cache };

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NgoKnows picture NgoKnows  路  40Comments

MarcoPolo picture MarcoPolo  路  67Comments

Gozala picture Gozala  路  54Comments

Macil picture Macil  路  47Comments

gabro picture gabro  路  57Comments