code: private void checkPropertyAccess(
        JSType childType,
        @Nullable Node getProp,
        JSType propType,
        Node propNode,
        @Nullable Node objNode) {
      String propName = propNode.getString();
      if (propType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
        childType = childType.autobox();
        ObjectType objectType = ObjectType.cast(childType);
        if (objectType != null) {
          // We special-case object types so that checks on enums can be
          // much stricter, and so that we can use hasProperty (which is much
          // faster in most cases).
          if (!objectType.hasProperty(propName)
              || objectType.isEquivalentTo(typeRegistry.getNativeType(UNKNOWN_TYPE))) {
            if (objectType instanceof EnumType) {
              report(getProp != null ? getProp : propNode, INEXISTENT_ENUM_ELEMENT, propName);
            } else {
              checkPropertyAccessHelper(objectType, propNode, objNode, getProp, false);
            }
          }
        } else {
          checkPropertyAccessHelper(childType, propNode, objNode, getProp, false);
        }
      } else if (childType.isUnionType() && getProp != null && !isLValueGetProp(getProp)) {
        // NOTE: strict property assignment checks are done on assignment.
        checkPropertyAccessHelper(childType, propNode, objNode, getProp, true);
      }
    }
docs: Emits a warning if we can prove that a property cannot possibly be defined on an object. Note
  the difference between JS and a strictly statically typed language: we're checking if the
  property *cannot be defined*, whereas a java compiler would check if the property *can be
  undefined.
  
  <p>This method handles property access in both GETPROPs and object destructuring.
  Consequentially some of its arguments are optional - the actual object node and the getprop -
  while others are required.
  
  @param objNode the actual node representing the object we're accessing. optional because
  destructuring accesses MAY not have an actual object node
  @param getProp the GETPROP node representing this property access. optional because
  destructuring accesses don't have actual getprops.