Error when using the spread operator in objects with optional property

599 Views Asked by At

I want to turn initial data into working data. Both have its own type, the only difference is that in the initial data, the names are optional. When I'm creating the working data, I use default value '__unknown__' for empty names.

Here is the example code:

/* @flow */

type NAME_OPTIONAL = {
  name?: string
}

type NAME_MANDATORY = {
  name: string
}

type INITIAL = {
  source: string,
  data: NAME_OPTIONAL[] // <-- Here the names are OPTIONAL.
}

type WORKING = {
  source: string,
  data: NAME_MANDATORY[] // <-- Here the name are MANDATORY.
}

// We have some initial data.
const initial: INITIAL = {
  source: 'some.server.com',
  data: [{ name: 'Adam' }, { name: undefined }]
}

// And we want to turn initial data into working data.
const workingData = initial.data.map((i) => {
  return { 
    name: i.name || '__unknown__'
  }
});

// This is OK:
const working1: WORKING = {
  source: initial.source, 
  data: workingData
}

// This is NOT OK:
const working2: WORKING = {
  ...initial,
  data: workingData
}

At the end of the example above initializing working1 is OK, but initializing working2, using the object spread operator, causes flowtype to show this error:

4:  name?: string
            ^ undefined. This type is incompatible with
8:  name: string
           ^ string

I don't understand how can the spread operator cause this. Can anybody explain it? Thank you.

"Working" example on https://flowtype.org/try/... is here.

1

There are 1 best solutions below

0
On BEST ANSWER

There are a lot of bugs about the spread operator. Your case seems identical to this one.

Probably no solution until they fix it, except replacing the operator with Object.assign:

const working2: WORKING = Object.assign({}, initial, { data: workingData })

If still not working, you can add an annotation above the line:

// $FlowIssue
const working2: WORKING = Object.assign({}, initial, { data: workingData })

Or:

// $FlowIssue
const working2: WORKING = {
  ...initial,
  data: workingData
}

And then add this setting in your .flowconfig:

[options]
suppress_comment=.*\\$FlowIssue

That will suppress the error.