Flow: Erratic error Property cannot be accessed on possibly undefined value

Created on 21 Dec 2016  路  4Comments  路  Source: facebook/flow

For the following code,

type Person = {name: string, email: string};
type bug = {id: string, assignee: ?Person}

var newBug : bug = {id:'bug1', assignee: null}

if (newBug.assignee) {
  console.log(newBug.assignee.name);
  console.log(newBug.assignee.email);  
}

Flow gives an error:

9:   console.log(newBug.assignee.email);  
                                 ^ property `email`. Property cannot be accessed on possibly null value
9:   console.log(newBug.assignee.email);  
                 ^ null
9:   console.log(newBug.assignee.email);  
                                 ^ property `email`. Property cannot be accessed on possibly undefined value
9:   console.log(newBug.assignee.email);  
                 ^ undefined

If I remove the second console.log, I get no errors. i.e, the following does not give any errors.

type Person = {name: string, email: string};
type bug = {id: string, assignee: ?Person}

var newBug : bug = {id:'bug1', assignee: null}

if (newBug.assignee) {
  console.log(newBug.assignee.name);  
}

Why?

Since both the console.log statements are within the if condition, I don't think the error should come in the first case as well.

Or at least, the behavior should be consistent and same error given in the second case.

The code can be tried at https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoALgTwA4FMwAKuATgM5wB2YAvGAN4UCGAtrgFxinrECWFA5gBowuZox4wOXXgIC+Abgw58AIwCu-GvR4ATKdz5CwjUqR78KudmAD8RMpVmpUAN0bEwlhACENYDuqatHS6bADkgQCMYcImZhZWHBRqMDBOqDxQYAAUXr78AHRx5pa4AJT0qGBgAMaU5DC4BfD8ubg+GkWmJVYFTKxlitV1FA1NLW0dhcUJTaLiMIPVqOlAA

Most helpful comment

See https://github.com/facebook/flow/issues/2986#issuecomment-265952300

Fix

const assignee = newBug.assignee
if (assignee) {
  console.log(assignee.name)
  console.log(assignee.email)
}

All 4 comments

See https://github.com/facebook/flow/issues/2986#issuecomment-265952300

Fix

const assignee = newBug.assignee
if (assignee) {
  console.log(assignee.name)
  console.log(assignee.email)
}

Ohk!

See #2986 (comment)

I disagree with it. In that example - asynchronous code, but even in async code, some situations can be correctly processed.

In the current example - simple synchronous code.
No one has the ability to change the data between if's predicate and console.log (If we are still talking about JS)

Flow doesn't treat console.log as a different function and considers that it can be unpure. Any function call will unvalidate refinements. There's a discussion somewhere to be able to declare functions as pure, but so far, nothing is settled.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Beingbook picture Beingbook  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

pelotom picture pelotom  路  3Comments

l2silver picture l2silver  路  3Comments

bennoleslie picture bennoleslie  路  3Comments