Flow: Union types & Default params

Created on 18 Jul 2016  路  6Comments  路  Source: facebook/flow

Search terms: destructuring, default arguments, default parameters, union

eg:

declare type Options = {
    a: null | Object,
    b: bool | Object,
}

function fn ({
    a = null, // errors here
    b = {} // errors here
} :Options = {}) {
    console.log(a, b);
}

let x :Options = {
    a: null, // No error
    b: {} // No error
};

It's strange that it happens only for default value assignment in object destructuring - fn and not an object definition - x.

This does NOT happen in Flow 0.28. But flow 0.29 throws errors.

unionintersections bug destructuring

Most helpful comment

@samwgoldman Any update on this? Similar issue in Flow v0.41.0:

// BlockTitle.js
// ...
type Props = {
  children?: React$Element<any>,
  className?: string,
  headerClassName?: string,
  size?: number | string,
  theme: Theme,
}

const BlockTitle = ({
  children,
  className = '',
  headerClassName = '',
  size = 3,
  theme,
}: Props) => {
// ...

And the error:

src/components/common/BlockTitle.js:18
 18:   size = 3,
       ^^^^ number. This type is incompatible with
 18:   size = 3,
       ^^^^ string

src/components/common/BlockTitle.js:18
 18:   size = 3,
       ^^^^ string. This type is incompatible with
 18:   size = 3,
       ^^^^ number

All 6 comments

@samwgoldman Any update on this? Similar issue in Flow v0.41.0:

// BlockTitle.js
// ...
type Props = {
  children?: React$Element<any>,
  className?: string,
  headerClassName?: string,
  size?: number | string,
  theme: Theme,
}

const BlockTitle = ({
  children,
  className = '',
  headerClassName = '',
  size = 3,
  theme,
}: Props) => {
// ...

And the error:

src/components/common/BlockTitle.js:18
 18:   size = 3,
       ^^^^ number. This type is incompatible with
 18:   size = 3,
       ^^^^ string

src/components/common/BlockTitle.js:18
 18:   size = 3,
       ^^^^ string. This type is incompatible with
 18:   size = 3,
       ^^^^ number

I think I'm seeing this same issue. Is there any progress being made on this? or any solid workarounds?

Here's my example I'm running into: tryflow example

Same here, also with state.

I'm running into this issue as well, to me it looks like an inconsistency in how Flow handles union types and destructuring with default values:

type Obj = { foo?: string | number };

// Error: "Cannot assign `{...}.foo` to `foo` because string [1] is incompatible with number [2]."
const { foo = 1 }: Obj = {};

// Works!
const obj: Obj = {};
const { foo: bar = 1 } = obj;

// Works!
const baz: $PropertyType<Obj, 'foo'> = 1;

(flow.org/try)

The first example exhibits the problem in question. The second problem is what I feel the first one ought to be equivalent to (unless I'm misunderstanding how the type syntax applies to the left-hand side of the assignment). The third example demonstrates that it isn't a problem with assignments to the union type itself, but only when the assignment happens as a default value when destructuring.

This is also seen in https://github.com/facebook/flow/issues/183#issuecomment-467164769. Possibly more issues as well.

I'm surprised this hasn't been addressed since it seems like a common case that a lot of people run into, and an interaction of fairly basic JS features. Perhaps it's just not a code style that's used much at facebook?

/cc @samwgoldman was this fixed?

Was this page helpful?
0 / 5 - 0 ratings