src/com/google/javascript/jscomp/TypeCheck.java
/**
   * Checks whether type (or one of its component if is composed type like union or templatized
   * type) has Object with non-stringifiable key. For example {@code Object.<!Object, number>}.
   *
   * @return non-stringifiable type which is used as key or null if all there are no such types.
   */
Checks whether type (or one of its component if is composed type like union or templatized
type) has Object with non-stringifiable key. For example  Object..

@return non-stringifiable type which is used as key or null if all there are no such types.
Checks whether type ( or one of its component if is composed type like union or templatized type ) has Object with non - stringifiable key . For example Object .. @return non - stringifiable type which is used as key or null if all there are no such types .
private JSType findObjectWithNonStringifiableKey(JSType type, Set<JSType> alreadyCheckedTypes) {
    if (alreadyCheckedTypes.contains(type)) {
      return null;
    } else {
      alreadyCheckedTypes.add(type);
    }
    if (isObjectTypeWithNonStringifiableKey(type)) {
      return type;
    }
    if (type.isUnionType()) {
      for (JSType alternateType : type.toMaybeUnionType().getAlternates()) {
        JSType result = findObjectWithNonStringifiableKey(alternateType, alreadyCheckedTypes);
        if (result != null) {
          return result;
        }
      }
    }
    if (type.isTemplatizedType()) {
      for (JSType templateType : type.toMaybeTemplatizedType().getTemplateTypes()) {
        JSType result = findObjectWithNonStringifiableKey(templateType, alreadyCheckedTypes);
        if (result != null) {
          return result;
        }
      }
    }
    if (type.isOrdinaryFunction()) {
      FunctionType function = type.toMaybeFunctionType();
      for (Node parameter : function.getParameters()) {
        JSType result =
            findObjectWithNonStringifiableKey(parameter.getJSType(), alreadyCheckedTypes);
        if (result != null) {
          return result;
        }
      }
      return findObjectWithNonStringifiableKey(function.getReturnType(), alreadyCheckedTypes);
    }
    return null;
  }
private JSType findObjectWithNonStringifiableKey ( JSType type , Set < JSType > alreadyCheckedTypes ) { if ( alreadyCheckedTypes . contains ( type ) ) { return null ; } else { alreadyCheckedTypes . add ( type ) ; } if ( isObjectTypeWithNonStringifiableKey ( type ) ) { return type ; } if ( type . isUnionType ( ) ) { for ( JSType alternateType : type . toMaybeUnionType ( ) . getAlternates ( ) ) { JSType result = findObjectWithNonStringifiableKey ( alternateType , alreadyCheckedTypes ) ; if ( result != null ) { return result ; } } } if ( type . isTemplatizedType ( ) ) { for ( JSType templateType : type . toMaybeTemplatizedType ( ) . getTemplateTypes ( ) ) { JSType result = findObjectWithNonStringifiableKey ( templateType , alreadyCheckedTypes ) ; if ( result != null ) { return result ; } } } if ( type . isOrdinaryFunction ( ) ) { FunctionType function = type . toMaybeFunctionType ( ) ; for ( Node parameter : function . getParameters ( ) ) { JSType result = findObjectWithNonStringifiableKey ( parameter . getJSType ( ) , alreadyCheckedTypes ) ; if ( result != null ) { return result ; } } return findObjectWithNonStringifiableKey ( function . getReturnType ( ) , alreadyCheckedTypes ) ; } return null ; }
Checks whether type (or one of its component if is composed type like union or templatized
 type) has Object with non-stringifiable key.
Checks whether type ( or one of its component if is composed type like union or templatized type ) has Object with non - stringifiable key .
// This can happen in recursive types. Current type already being checked earlier in // stacktrace so now we just skip it.