code: private void visitObjectPattern(Node pattern) {
      JSType patternType = getJSType(pattern);
      validator.expectObject(pattern, patternType, "cannot destructure 'null' or 'undefined'");
      for (Node child : pattern.children()) {
        DestructuredTarget target = DestructuredTarget.createTarget(typeRegistry, patternType, child);
  
        if (target.hasComputedProperty()) {
          Node computedProperty = target.getComputedProperty();
          validator.expectIndexMatch(
              computedProperty, patternType, getJSType(computedProperty.getFirstChild()));
        } else if (target.hasStringKey()) {
          Node stringKey = target.getStringKey();
          if (!stringKey.isQuotedString()) {
            if (patternType.isDict()) {
              report(stringKey, TypeValidator.ILLEGAL_PROPERTY_ACCESS, "unquoted", "dict");
            }
            // check for missing properties given `const {a} = obj;` but not `const {'a': a} = obj;`
            checkPropertyAccessForDestructuring(
                pattern, patternType, stringKey, getJSType(target.getNode()));
          } else if (patternType.isStruct()) {
            // check that we are not accessing a struct with a quoted string
            report(stringKey, TypeValidator.ILLEGAL_PROPERTY_ACCESS, "quoted", "struct");
          }
        }
      }
      ensureTyped(pattern);
    }
docs: Validates all keys in an object pattern
  
  <p>Validating the types assigned to any lhs nodes in the pattern is done at the ASSIGN/VAR/
  PARAM_LIST/etc. node