Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flow freezes when 'merging inference' #2702

Closed
villesau opened this issue Oct 28, 2016 · 6 comments
Closed

Flow freezes when 'merging inference' #2702

villesau opened this issue Oct 28, 2016 · 6 comments

Comments

@villesau
Copy link
Contributor

villesau commented Oct 28, 2016

Flow checker freezes completely with following code:

// @flow
import React from 'react';
import _ from 'lodash';

export default class Test extends React.Component {

  state: {matrix: Array<Array<boolean>>};
  state = {matrix: _.times(5, () => _.times(5, () => false))};

  toggleCell(rowIndex: number, columnIndex: number) {
    const newRow = this.state.matrix[rowIndex];
    this.setState({matrix: _.set(this.state.matrix, rowIndex, newRow)})
  }

  render() {
    return (<div onClick={() => this.toggleCell(1, 1)}></div>);
  }
}

my flow definitions for lodash looks like following:

declare module 'lodash' {
  declare function set(object?: ?Object, path?: ?Array<string>|string, value: any): Object;
  declare function set<T>(array: Array<T>, index: number, value: T): Array<T>;
  declare function times<T>(n: number, iteratee: (i: number) => T): Array<T>;
}

few ways how i can get it fixed:
(1. Move state = {matrix: _.times(5, () => _.times(5, () => false))};
to constructor:

export default class Test extends React.Component {

  state: {matrix: Array<Array<boolean>>};

  constructor() {
    super();
    this.state = {matrix: _.times(5, () => _.times(5, () => false))};
  }

  toggleCell(rowIndex: number, columnIndex: number) {
    const newRow = this.state.matrix[rowIndex];
    this.setState({matrix: _.set(this.state.matrix, rowIndex, newRow)})
  }

  render() {
    return (<div onClick={() => this.toggleCell(1, 1)}></div>);
  }
}

(2. Declare _.times to return any: declare function times<T>(n: number, iteratee: (i: number) => T): any;

(3. Remove _.set: this.setState({matrix: this.state.matrix})

  toggleCell(rowIndex: number, columnIndex: number) {
    const newRow = this.state.matrix[rowIndex];
    this.setState({matrix: this.state.matrix})
  }

Anyone of above is not optimal solution, and last of them breaks the logic. Just wanted to point it out to narrow the problem.

declaring state outside of the constructor should be valid javascript. Webpack&babel compiles it just fine and it works like expected.

@gcanti
Copy link

gcanti commented Oct 28, 2016

state: {matrix: Array<Array<boolean>>} = {matrix: _.times(5, () => _.times(5, () => false))};

@villesau
Copy link
Contributor Author

thanks @gcanti :) Somehow my mind was stuck with approach i had since usually we define type of state and initialize it separately in the constructor.

Anyhow in my original scenario flow should either be a) error b) it should succeed without freezing.

@MoOx
Copy link

MoOx commented Mar 10, 2017

Looks similar to #1570 somehow (> "something" flow does not like make it ultra slow)

@TrySound
Copy link
Contributor

Is this still relevant?

@villesau
Copy link
Contributor Author

Not relevant to me anymore. Not sure if the issue would still exist though.

@TrySound
Copy link
Contributor

This probably can be closed in favor of newer feedback.
/cc @vkurchatkin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants