Flow: Truthy optional object potentially void after calling a function

Created on 16 Jan 2020  路  1Comment  路  Source: facebook/flow

Flow version: 0.114.0, still present in 0.116.0

Expected behavior

A truthy optional nested object (obj.a) cannot be undefined after calling a function.

Actual behavior

A truthy optional nested object (obj.a) reverts back to potentially void after calling a function.

Try Flow Reproduction

This showed up when conditionally rendering a component:

type MyProps = {|
  a?: {
    b: string
  }
|}

function MyComponent(props: MyProps) {
  return (
    props.a && (
      <button href={run(props.a.b)}>
        {props.a.b}  
      </button>
    )
  )
};

Which results in the following error:

{props.a.b}  
         ^ Cannot get `props.a.b` because property `b` is missing in undefined [1].
not a bug

Most helpful comment

This has always been the behaviour and it's very much intentional. See Type refinement invalidations in the docs. Calling run could potentially modify props.a to be null again. Extract the property to a local value and it works

function MyComponent(props: MyProps) {
  const {a} = props
  return (
    a && (
      <button href={run(a.b)}>
        {a.b}  
      </button>
    )
  )
};

>All comments

This has always been the behaviour and it's very much intentional. See Type refinement invalidations in the docs. Calling run could potentially modify props.a to be null again. Extract the property to a local value and it works

function MyComponent(props: MyProps) {
  const {a} = props
  return (
    a && (
      <button href={run(a.b)}>
        {a.b}  
      </button>
    )
  )
};

Was this page helpful?
0 / 5 - 0 ratings