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

function that takes argument with multiple possible types throws error #4270

Closed
FezVrasta opened this issue Jun 28, 2017 · 3 comments
Closed

Comments

@FezVrasta
Copy link
Contributor

FezVrasta commented Jun 28, 2017

/* @flow */

type Props = {
  width: string | number,
};

function fun({
  width = '30em',
}: Props) {
  return width;
}

It complains with:

8:   width = '30em',
     ^ number. This type is incompatible with
8:   width = '30em',
     ^ string
8:   width = '30em',
     ^ string. This type is incompatible with
8:   width = '30em',
     ^ number
8:   width = '30em',
             ^ string. This type is incompatible with
8:   width = '30em',
     ^ number

repro

post updated

@steelbrain
Copy link

It's actually correctly saying that, the repro fails on even babel parsing. link

What you want to do is

/* @flow */

type Props = {
  width: string | number,
};

function MyComponent({
  width = '30rem',
}: Props) {
  return <div style={{ width }} />
}

@FezVrasta
Copy link
Contributor Author

Sorry it was a typo... On my project it failing the code you provided.
I'm going to try to reproduce it

@FezVrasta
Copy link
Contributor Author

FezVrasta commented Jun 29, 2017

I updated the repro fixing the typo, the correct error is shown now.

I also simplified the example to remove React from the equation.

If it helps, the function works properly without any type error if I use it without any default value set:
https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgAKATnDgM5gC8YA3qmGAgJYAmGAFgFxgB2ArgFsARnmJgAPmHIZizXgHMANKgC+AbnRR+vAMYZmcXmG28AFPUYt2HNTxJlyASjoMwxPBn7Fj1zptV0VFMLJjZOHgBGAAYwVSdgnVC-bjAAcgAmaLxBNLinIA

It also works if I move the props object destructuring inside the function:
https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgAKATnDgM5gC8YA3qmGAgJYAmGAFgFxgB2ArgFsARnmJgAPmHIZizXgHMANKgC+AbnRR+vAMYZmcXmG28AFDlIUeJMuQCUdBmF1GZTxoxbsO1MAHIAZgAGPEF-FUZVP0s7TWdiPAx+YmNvTk1VIA

@FezVrasta FezVrasta changed the title property with multiple type (string or number) throwing error function that takes argument with multiple possible types throws error Jun 29, 2017
facebook-github-bot pushed a commit that referenced this issue Jul 15, 2019
Summary:
Bindings introduced by destructuring a type annotation should behave as
annotations themselves. That is, `p` in `var {p}: {p: T}` should constrain any
subsequent write to be a subtype of `T`.

This logic works today by wrapping the binding in an AnnotT using BecomeT
internally, which works for most cases. However, since BecomeT performs
unification, it is necessary that its lower bound be resolve once and exactly
once.

The once-and-exactly-once invariant is broken by union-like types when combined
with the destructuring operation. Consider the following example:

```
var {p}: {p:string}|{p:number} = ...
```

When evaluating this variable declaration, we emit the following constraints:

1. {p:string}|{p:number} -> GetPropT ('p', T)
2. T -> BecomeT T'
3. P = T'

Constraint (1) is processed by splitting the lower bound, which turns into two
separate constraints `string -> T` and `number -> T`. Since `T` resolves twice,
the `BecomeT` constraint misbehaves and we see a spurious error that `number` is
not compatible with `string`.

This diff deals with the above by handling union-like types specially in the
`DestructuringT` use type.

Fixes #183
Fixes #2198
Fixes #2220
Fixes #4077
Fixes #4270
Fixes #5461
Fixes #5745
Fixes #6408

Reviewed By: panagosg7

Differential Revision: D15457398

fbshipit-source-id: 22c9aba1e1df475c73b36a92bdf7ff5cf57504a6
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

2 participants