weird `Method cannot be called on possibly null / undefined value`

Your case is described here.

Flow cannot know, that assert doesn't change the tree. Add the following lines to your code and run it – you will have runtime error, because assert function will set tree.children to null when called.

const root = new Node(1);
const child = new Node(2);

root.children = new Map([['child', child]]);

assert = () => root.children = null;

accessChildren(root);

Yes, it is pretty weird code, but Flow doesn't know, you will not to write it.


Others have pointed to the right explanation. Fortunately this works:

// @flow
'use strict';

import assert from 'assert';

class Node<V, E> {
  value: V;
  children: ?Map<E, Node<V, E>>;

  constructor(value: V) {
    this.value = value;
    this.children = null;
  }
}

function accessChildren(tree: Node<number, string>): void {
  const children = tree.children; // save possibly mutable reference to local
  if (children != null) {
    assert(true); // if you comment this line Flow is ok
    children.forEach((v, k) => {});
  } else {
  }
}

Also, in the future Flow will have read-only properties and by declaring children as a read-only property in the class, Flow should be able to preserve type check the original code.

Tags:

Flowtype