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 unable to understand trivial variable equivalence when determining refinements #7228

Open
rkrv opened this issue Dec 4, 2018 · 5 comments
Labels
incompleteness Something is missing

Comments

@rkrv
Copy link

rkrv commented Dec 4, 2018

I ran into a issue where flow will not recognise a type of a copied variable for conditional rendering in React:

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBLAtgBzgJwBcwAlAUwEMBjYqfOLMAcn0pqYG50q4A7AZ2IAVMgA9iAXjAAKAN5gAFoSwwwAXwBcYeUpVbB+DLwDm6gJRgJAPkXKYXVFACuvGhj5gA6vgo4cZfDlbFXUtHTsAfn1CQxNzbVQwMB4BYgUKfgAJO0tg+0SwVkInfF5FDOyQgDIqsAAeEXE8iVldGDUwYCsuNVQgA

const Text = ({ html }: { html: string }) => html;

function Wrapper({ html }: { html?: string }) {
  const hasHtml = html;
  return hasHtml && <Text html={html} />;
}

Funny enough, this will work:

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBLAtgBzgJwBcwAlAUwEMBjYqfOLMAcn0pqYG50q4A7AZ2IAVMgA9iAXjAAKAN5gAFoSwwwAXwBcYeUpVbB+DLwDm6gJRgJAPkXKYXVFACuvGhj5gA6vgo4cZfDlbFXUtHTsAfn1CQxNzbVQwMGBgMB4BYgUKfgAJO0tg+0SwVkInfF5CsAAyarAAHhFxQolZXRg1ZKsuNVQgA

const Text = ({ html }: { html: string }) => html;

function Wrapper({ html }: { html?: string }) {
  return html && <Text html={html} />;
}

Am I missing something?

@TrySound
Copy link
Contributor

TrySound commented Dec 4, 2018

Refinements are not saved with new variables. It's expected behaviour. Just use already refined variable.

@rkrv
Copy link
Author

rkrv commented Dec 4, 2018

Just use already refined variable.

That becomes complicated in larger scenarios, like:

const Text = ({ html, heading }: { html: string, heading: string }) => (
  <div>
    {heading}
    {html}
  </div>
);

function Wrapper({ html, heading }: { html?: string, heading?: string }) {
  const hasContent = html && heading;
  return hasContent && <Text html={html} heading={heading} />;
}

@jbrown215 jbrown215 added the incompleteness Something is missing label Dec 4, 2018
@jbrown215
Copy link
Contributor

Unfortunately, our refinement tracking is very conservative and cannot support your use case today. There is no one currently working on making our refinement tracking more complete.

@rkrv
Copy link
Author

rkrv commented Dec 5, 2018

Thanks for your quick reply, @jbrown215! I'd be interested in helping with testing when somebody picks up this task.

@villesau
Copy link
Contributor

villesau commented Dec 7, 2018

@rkrv I got very definite answer to same problem here: #6146 (comment)

This has been reported many times already. I think that it's because the restriction is not well documented and the use case is pretty idiomatic JS. If you know the restriction, it's very easy to avoid it and still being able write clean code. Just avoid destructing objects that has this kind of "cross dependencies"

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

No branches or pull requests

4 participants