diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
index f801c28..4a3b896 100644
--- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
+++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
@@ -6,17 +6,12 @@
  */
 
 namespace Drupal\Core\Config\Schema;
-
-use \ArrayAccess;
-use \ArrayIterator;
-use \Countable;
-use \IteratorAggregate;
-use \Traversable;
+use Drupal\Core\TypedData\TraversableTypedDataInterface;
 
 /**
  * Defines a generic configuration element that contains multiple properties.
  */
-abstract class ArrayElement extends Element implements IteratorAggregate, ArrayAccess, Countable {
+abstract class ArrayElement extends Element implements \IteratorAggregate, TraversableTypedDataInterface, \ArrayAccess, \Countable {
 
   /**
    * Parsed elements.
@@ -26,8 +21,8 @@
   /**
    * Gets an array of contained elements.
    *
-   * @return array
-   *   Array of \Drupal\Core\Config\Schema\ArrayElement objects.
+   * @return \Drupal\Core\TypedData\TypedDataInterface[]
+   *   An array of elements contained in this element.
    */
   protected function getElements() {
     if (!isset($this->elements)) {
@@ -49,8 +44,8 @@ protected function getAllKeys() {
   /**
    * Builds an array of contained elements.
    *
-   * @return array
-   *   Array of \Drupal\Core\Config\Schema\ArrayElement objects.
+   * @return \Drupal\Core\TypedData\TypedDataInterface
+   *   An array of elements contained in this element.
    */
   protected abstract function parse();
 
@@ -111,7 +106,7 @@ public function count() {
    * Implements IteratorAggregate::getIterator();
    */
   public function getIterator() {
-    return new ArrayIterator($this->getElements());
+    return new \ArrayIterator($this->getElements());
   }
 
 }
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
index 0836eaf..93bf05e 100644
--- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
+++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\TypedData\PrimitiveInterface;
+use Drupal\Core\TypedData\TraversableTypedDataInterface;
 use Drupal\Core\TypedData\Type\BooleanInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
@@ -107,7 +108,7 @@ protected function checkValue($key, $value) {
     }
     else {
       $errors = array();
-      if (!$element instanceof ArrayElement) {
+      if (!$element instanceof TraversableTypedDataInterface) {
         $errors[$error_key] = 'Non-scalar value but not defined as an array (such as mapping or sequence).';
       }
 
diff --git a/core/lib/Drupal/Core/Config/Schema/Sequence.php b/core/lib/Drupal/Core/Config/Schema/Sequence.php
index e5b6a35..630bb50 100644
--- a/core/lib/Drupal/Core/Config/Schema/Sequence.php
+++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
@@ -22,7 +22,7 @@ class Sequence extends ArrayElement implements ListInterface {
   protected $itemDefinition;
 
   /**
-   * Overrides ArrayElement::parse()
+   * {@inheritdoc}
    */
   protected function parse() {
     // Creates a new data definition object for each item from the generic type
diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
index 1397485..0a5b38a 100644
--- a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
+++ b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php
@@ -23,7 +23,7 @@
  *
  * @ingroup typed_data
  */
-interface ComplexDataInterface extends \Traversable, TypedDataInterface  {
+interface ComplexDataInterface extends TraversableTypedDataInterface  {
 
   /**
    * Gets a property object.
diff --git a/core/lib/Drupal/Core/TypedData/ListInterface.php b/core/lib/Drupal/Core/TypedData/ListInterface.php
index ce59dfb..2c5dbc7 100644
--- a/core/lib/Drupal/Core/TypedData/ListInterface.php
+++ b/core/lib/Drupal/Core/TypedData/ListInterface.php
@@ -20,7 +20,7 @@
  *
  * @ingroup typed_data
  */
-interface ListInterface extends TypedDataInterface, \ArrayAccess, \Countable, \Traversable {
+interface ListInterface extends TraversableTypedDataInterface, \ArrayAccess, \Countable {
 
   /**
    * Determines whether the list contains any non-empty items.
diff --git a/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php
new file mode 100644
index 0000000..d42557e
--- /dev/null
+++ b/core/lib/Drupal/Core/TypedData/TraversableTypedDataInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\TypedData\TraversableTypedDataInterface.
+ */
+
+namespace Drupal\Core\TypedData;
+
+/**
+ * An interface for typed data objects that can be traversed.
+ */
+interface TraversableTypedDataInterface extends TypedDataInterface, \Traversable {}
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php
index 74d083f..0e63301 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataInterface.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataInterface.php
@@ -122,7 +122,7 @@ public function getName();
   /**
    * Returns the parent data structure; i.e. either complex data or a list.
    *
-   * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface
+   * @return \Drupal\Core\TypedData\TraversableTypedDataInterface|null
    *   The parent data structure, either complex data or a list; or NULL if this
    *   is the root of the typed data tree.
    */
@@ -134,7 +134,7 @@ public function getParent();
    * Returns the root data for a tree of typed data objects; e.g. for an entity
    * field item the root of the tree is its parent entity object.
    *
-   * @return \Drupal\Core\TypedData\ComplexDataInterface|\Drupal\Core\TypedData\ListInterface
+   * @return \Drupal\Core\TypedData\TraversableTypedDataInterface
    *   The root data structure, either complex data or a list.
    */
   public function getRoot();
diff --git a/core/modules/config_translation/src/ConfigMapperManager.php b/core/modules/config_translation/src/ConfigMapperManager.php
index 9a0b46e..09b6498 100644
--- a/core/modules/config_translation/src/ConfigMapperManager.php
+++ b/core/modules/config_translation/src/ConfigMapperManager.php
@@ -10,7 +10,6 @@
 use Drupal\Component\Utility\String;
 use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Config\Schema\ArrayElement;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -20,6 +19,7 @@
 use Drupal\Core\Plugin\Discovery\YamlDiscovery;
 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
 use Drupal\Core\Plugin\Factory\ContainerFactory;
+use Drupal\Core\TypedData\TraversableTypedDataInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -176,7 +176,7 @@ public function hasTranslatable($name) {
   protected function findTranslatable(TypedDataInterface $element) {
     // In case this is a sequence or a mapping check whether any child element
     // is translatable.
-    if ($element instanceof ArrayElement) {
+    if ($element instanceof TraversableTypedDataInterface) {
       foreach ($element as $child_element) {
         if ($this->findTranslatable($child_element)) {
           return TRUE;
diff --git a/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php b/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php
index c28b663..cdf89b5 100644
--- a/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php
+++ b/core/modules/config_translation/tests/src/Unit/ConfigMapperManagerTest.php
@@ -170,9 +170,12 @@ protected function getElement(array $definition) {
    *   A nested schema element, containing the passed-in elements.
    */
   protected function getNestedElement(array $elements) {
-    // ConfigMapperManager::findTranslatable() checks for the abstract class
-    // \Drupal\Core\Config\Schema\ArrayElement, but mocking that directly does
-    // not work.
+    // ConfigMapperManager::findTranslatable() checks for
+    // \Drupal\Core\TypedData\TraversableTypedDataInterface, but mocking that
+    // directly does not work, because we need to implement \IteratorAggregate
+    // in order for getIterator() to be called. Therefore we need to mock
+    // \Drupal\Core\Config\Schema\ArrayElement, but that is abstract, so we
+    // need to mock one of the subclasses of it.
     $nested_element = $this->getMockBuilder('Drupal\Core\Config\Schema\Mapping')
       ->disableOriginalConstructor()
       ->getMock();
diff --git a/core/modules/locale/src/LocaleTypedConfig.php b/core/modules/locale/src/LocaleTypedConfig.php
index ab373fe..f4c0138 100644
--- a/core/modules/locale/src/LocaleTypedConfig.php
+++ b/core/modules/locale/src/LocaleTypedConfig.php
@@ -10,8 +10,9 @@
 use Drupal\Core\TypedData\ContextAwareInterface;
 use Drupal\Core\TypedData\DataDefinitionInterface;
 use Drupal\Core\Config\Schema\Element;
-use Drupal\Core\Config\Schema\ArrayElement;
 use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\TypedData\TraversableTypedDataInterface;
+use Drupal\Core\TypedData\TypedDataInterface;
 
 /**
  * Defines the locale configuration wrapper object.
@@ -114,9 +115,8 @@ protected function canTranslate($from_langcode, $to_langcode) {
   /**
    * Gets translated configuration data for a typed configuration element.
    *
-   * @param mixed $element
-   *   Typed configuration element, either \Drupal\Core\Config\Schema\Element or
-   *   \Drupal\Core\Config\Schema\ArrayElement.
+   * @param \Drupal\Core\TypedData\TypedDataInterface $element
+   *   Typed configuration element.
    * @param array $options
    *   Array with translation options that must contain the keys defined in
    *   \Drupal\locale\LocaleTypedConfig::translateElement().
@@ -125,9 +125,9 @@ protected function canTranslate($from_langcode, $to_langcode) {
    *   Configuration data translated to the requested language if available,
    *   an empty array otherwise.
    */
-  protected function getElementTranslation($element, array $options) {
+  protected function getElementTranslation(TypedDataInterface $element, array $options) {
     $translation = array();
-    if ($element instanceof ArrayElement) {
+    if ($element instanceof \Traversable) {
       $translation = $this->getArrayTranslation($element, $options);
     }
     elseif ($this->translateElement($element, $options)) {
@@ -137,9 +137,9 @@ protected function getElementTranslation($element, array $options) {
   }
 
   /**
-   * Gets translated configuration data for an element of type ArrayElement.
+   * Gets translated configuration data for a traversable element.
    *
-   * @param \Drupal\Core\Config\Schema\ArrayElement $element
+   * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $element
    *   Typed configuration array element.
    * @param array $options
    *   Array with translation options that must contain the keys defined in
@@ -148,7 +148,7 @@ protected function getElementTranslation($element, array $options) {
    * @return array
    *   Configuration data translated to the requested language.
    */
-  protected function getArrayTranslation(ArrayElement $element, array $options) {
+  protected function getArrayTranslation(TraversableTypedDataInterface $element, array $options) {
     $translation = array();
     foreach ($element as $key => $property) {
       $value = $this->getElementTranslation($property, $options);
@@ -179,7 +179,7 @@ protected function getArrayTranslation(ArrayElement $element, array $options) {
    * @return bool
    *   Whether the element fits the translation criteria.
    */
-  protected function translateElement(\Drupal\Core\TypedData\TypedDataInterface $element, array $options) {
+  protected function translateElement(TypedDataInterface $element, array $options) {
     if ($this->canTranslate($options['source'], $options['target'])) {
       $definition = $element->getDataDefinition();
       $value = $element->getValue();
