diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 7621a48..9c814b8 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -459,7 +459,7 @@ public static function moduleHandler() {
    *
    * Use the typed data manager service for creating typed data objects.
    *
-   * @return \Drupal\Core\TypedData\TypedDataManager
+   * @return \Drupal\Core\TypedData\TypedDataManagerInterface
    *   The typed data manager.
    *
    * @see \Drupal\Core\TypedData\TypedDataManager::create()
diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
index 88914c0..616f2f9 100644
--- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
+++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
@@ -7,27 +7,10 @@
 
 namespace Drupal\Core\Config\Schema;
 
-use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\TypedData\TypedData;
-
 /**
  * Defines a generic configuration element that contains multiple properties.
  */
-abstract class ArrayElement extends TypedData implements \IteratorAggregate, TypedConfigInterface {
-
-  /**
-   * The typed config manager.
-   *
-   * @var \Drupal\Core\Config\TypedConfigManagerInterface
-   */
-  protected $typedConfig;
-
-  /**
-   * The configuration value.
-   *
-   * @var mixed
-   */
-  protected $value;
+abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
 
   /**
    * Parsed elements.
@@ -152,7 +135,7 @@ public function getIterator() {
    * @return \Drupal\Core\TypedData\TypedDataInterface
    */
   protected function createElement($definition, $value, $key) {
-    return $this->typedConfig->create($definition, $value, $key, $this);
+    return $this->getTypedDataManager()->create($definition, $value, $key, $this);
   }
 
   /**
@@ -170,20 +153,7 @@ protected function createElement($definition, $value, $key) {
    * @return \Drupal\Core\TypedData\DataDefinitionInterface
    */
   protected function buildDataDefinition($definition, $value, $key) {
-    return $this->typedConfig->buildDataDefinition($definition, $value, $key, $this);
-  }
-
-
-  /**
-   * Sets the typed config manager on the instance.
-   *
-   * This must be called immediately after construction to enable
-   * self::parseElement() and self::buildDataDefinition() to work.
-   *
-   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
-   */
-  public function setTypedConfig(TypedConfigManagerInterface $typed_config) {
-    $this->typedConfig = $typed_config;
+    return $this->getTypedDataManager()->buildDataDefinition($definition, $value, $key, $this);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Config/Schema/Element.php b/core/lib/Drupal/Core/Config/Schema/Element.php
index 2993f8c..54a4882 100644
--- a/core/lib/Drupal/Core/Config/Schema/Element.php
+++ b/core/lib/Drupal/Core/Config/Schema/Element.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Config\Schema;
 
 use Drupal\Core\TypedData\TypedData;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 
 /**
  * Defines a generic configuration element.
@@ -21,4 +22,41 @@
    */
   protected $value;
 
+  /**
+   * Gets the typed configuration manager.
+   *
+   * Overrides \Drupal\Core\TypedData\TypedDataTrait::getTypedDataManager() to
+   * ensure the typed configuration manager is returned.
+   *
+   * @return \Drupal\Core\Config\TypedConfigManagerInterface
+   *   The typed configuration manager.
+   */
+  public function getTypedDataManager() {
+    if (empty($this->typedDataManager)) {
+      $this->setTypedDataManager(\Drupal::service('config.typed'));
+    }
+
+    return $this->typedDataManager;
+  }
+
+  /**
+   * Sets the typed config manager.
+   *
+   * Overrides \Drupal\Core\TypedData\TypedDataTrait::setTypedDataManager() to
+   * ensure that only typed configuration manager can be used.
+   *
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
+   *   The typed config manager. This must be an instance of
+   *   \Drupal\Core\Config\TypedConfigManagerInterface. If it is not, then this
+   *   method will error when assertions are enabled. We can not narrow the
+   *   typehint as this will cause PHP errors.
+   *
+   * @return $this
+   */
+  public function setTypedDataManager(TypedDataManagerInterface $typed_data_manager) {
+    assert('$typed_data_manager instanceof \Drupal\Core\Config\TypedConfigManagerInterface');
+    $this->typedDataManager = $typed_data_manager;
+    return $this;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index 500fc3c..084f920 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -71,13 +71,7 @@ protected function getDiscovery() {
 
 
   /**
-   * Gets typed configuration data.
-   *
-   * @param string $name
-   *   Configuration object name.
-   *
-   * @return \Drupal\Core\Config\Schema\TypedConfigInterface
-   *   Typed configuration data.
+   * {@inheritdoc}
    */
   public function get($name) {
     $data = $this->configStorage->read($name);
@@ -338,17 +332,4 @@ protected function alterDefinitions(&$definitions) {
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function createInstance($data_type, array $configuration = array()) {
-    $instance = parent::createInstance($data_type, $configuration);
-    // Enable elements to construct their own definitions using the typed config
-    // manager.
-    if ($instance instanceof ArrayElement) {
-      $instance->setTypedConfig($this);
-    }
-    return $instance;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php b/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
index 11c3751..dcd8584 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
@@ -7,9 +7,7 @@
 
 namespace Drupal\Core\Config;
 
-use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
-use Drupal\Component\Plugin\PluginManagerInterface;
-use Drupal\Core\TypedData\DataDefinitionInterface;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 
 /**
  * Defines an interface for managing config schema type plugins.
@@ -19,7 +17,7 @@
  * @see hook_config_schema_info_alter()
  * @see https://www.drupal.org/node/1905070
  */
-Interface TypedConfigManagerInterface extends PluginManagerInterface, CachedDiscoveryInterface {
+Interface TypedConfigManagerInterface extends TypedDataManagerInterface {
 
   /**
    * Gets typed configuration data.
@@ -33,48 +31,6 @@
   public function get($name);
 
   /**
-   * Instantiates a typed configuration object.
-   *
-   * @param string $data_type
-   *   The data type, for which a typed configuration object should be
-   *   instantiated.
-   * @param array $configuration
-   *   The plugin configuration array, i.e. an array with the following keys:
-   *   - data definition: The data definition object, i.e. an instance of
-   *     \Drupal\Core\TypedData\DataDefinitionInterface.
-   *   - name: (optional) If a property or list item is to be created, the name
-   *     of the property or the delta of the list item.
-   *   - parent: (optional) If a property or list item is to be created, the
-   *     parent typed data object implementing either the ListInterface or the
-   *     ComplexDataInterface.
-   *
-   * @return \Drupal\Core\Config\Schema\Element
-   *   The instantiated typed configuration object.
-   */
-  public function createInstance($data_type, array $configuration = array());
-
-  /**
-   * Creates a new typed configuration object instance.
-   *
-   * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
-   *   The data definition of the typed data object.
-   * @param mixed $value
-   *   The data value. If set, it has to match one of the supported
-   *   data type format as documented for the data type classes.
-   * @param string $name
-   *   (optional) If a property or list item is to be created, the name of the
-   *   property or the delta of the list item.
-   * @param mixed $parent
-   *   (optional) If a property or list item is to be created, the parent typed
-   *   data object implementing either the ListInterface or the
-   *   ComplexDataInterface.
-   *
-   * @return \Drupal\Core\Config\Schema\Element
-   *   The instantiated typed data object.
-   */
-  public function create(DataDefinitionInterface $definition, $value, $name = NULL, $parent = NULL);
-
-  /**
    * Creates a new data definition object from a type definition array and
    * actual configuration data. Since type definitions may contain variables
    * to be replaced, we need the configuration value to create it.
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index ad0002e..4904e95 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -32,7 +32,7 @@
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\Core\TypedData\TranslatableInterface;
-use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -111,7 +111,7 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
   /**
    * The typed data manager.
    *
-   * @var \Drupal\Core\TypedData\TypedDataManager
+   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
    */
   protected $typedDataManager;
 
@@ -193,14 +193,14 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
    *   The string translationManager.
    * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
    *   The class resolver.
-   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
    *   The typed data manager.
    * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
    *   The keyvalue factory.
    * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
    *   The event dispatcher.
    */
-  public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManager $typed_data_manager, KeyValueFactoryInterface $key_value_factory, EventDispatcherInterface $event_dispatcher) {
+  public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, TranslationInterface $translation_manager, ClassResolverInterface $class_resolver, TypedDataManagerInterface $typed_data_manager, KeyValueFactoryInterface $key_value_factory, EventDispatcherInterface $event_dispatcher) {
     parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityInterface');
 
     $this->setCacheBackend($cache, 'entity_type', array('entity_types'));
diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php
index 1067ae8..4e775d2 100644
--- a/core/lib/Drupal/Core/Field/FieldItemList.php
+++ b/core/lib/Drupal/Core/Field/FieldItemList.php
@@ -281,7 +281,7 @@ public function getConstraints() {
     // widgets.
     $cardinality = $this->getFieldDefinition()->getFieldStorageDefinition()->getCardinality();
     if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
-      $constraints[] = \Drupal::typedDataManager()
+      $constraints[] = $this->getTypedDataManager()
         ->getValidationConstraintManager()
         ->create('Count', array(
           'max' => $cardinality,
diff --git a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
index 000e3fe..3d896b2 100644
--- a/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
+++ b/core/lib/Drupal/Core/Field/FieldTypePluginManager.php
@@ -13,7 +13,7 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\CategorizingPluginManagerTrait;
 use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 
 /**
  * Plugin manager for 'field type' plugins.
@@ -27,7 +27,7 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
   /**
    * The typed data manager.
    *
-   * @var \Drupal\Core\TypedData\TypedDataManager
+   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
    */
   protected $typedDataManager;
 
@@ -41,10 +41,10 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
    *   Cache backend instance to use.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface
    *   The module handler.
-   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
    *   The typed data manager.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManager $typed_data_manager) {
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManagerInterface $typed_data_manager) {
     parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\FieldItemInterface', 'Drupal\Core\Field\Annotation\FieldType');
     $this->alterInfo('field_info');
     $this->setCacheBackend($cache_backend, 'field_types_plugins');
diff --git a/core/lib/Drupal/Core/TypedData/DataReferenceBase.php b/core/lib/Drupal/Core/TypedData/DataReferenceBase.php
index 1b9aaa5..4ad77bd 100644
--- a/core/lib/Drupal/Core/TypedData/DataReferenceBase.php
+++ b/core/lib/Drupal/Core/TypedData/DataReferenceBase.php
@@ -48,7 +48,7 @@ public function getValue() {
    * {@inheritdoc}
    */
   public function setValue($value, $notify = TRUE) {
-    $this->target = \Drupal::typedDataManager()->create($this->definition->getTargetDefinition(), $value);
+    $this->target = $this->getTypedDataManager()->create($this->definition->getTargetDefinition(), $value);
     // Notify the parent of any changes.
     if ($notify && isset($this->parent)) {
       $this->parent->onChange($this->name);
diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
index 2a868db..577bfb4 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php
@@ -222,7 +222,7 @@ public function appendItem($value = NULL) {
    * @return \Drupal\Core\TypedData\TypedDataInterface
    */
   protected function createItem($offset = 0, $value = NULL) {
-    return \Drupal::typedDataManager()->getPropertyInstance($this, $offset, $value);
+    return $this->getTypedDataManager()->getPropertyInstance($this, $offset, $value);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
index 7694db5..6c0332b 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
@@ -128,7 +128,7 @@ public function get($property_name) {
         $value = $this->values[$property_name];
       }
       // If the property is unknown, this will throw an exception.
-      $this->properties[$property_name] = \Drupal::typedDataManager()->getPropertyInstance($this, $property_name, $value);
+      $this->properties[$property_name] = $this->getTypedDataManager()->getPropertyInstance($this, $property_name, $value);
     }
     return $this->properties[$property_name];
   }
diff --git a/core/lib/Drupal/Core/TypedData/TypedData.php b/core/lib/Drupal/Core/TypedData/TypedData.php
index 92c8a89..a266daa 100644
--- a/core/lib/Drupal/Core/TypedData/TypedData.php
+++ b/core/lib/Drupal/Core/TypedData/TypedData.php
@@ -21,6 +21,7 @@
 abstract class TypedData implements TypedDataInterface, PluginInspectionInterface {
 
   use StringTranslationTrait;
+  use TypedDataTrait;
 
   /**
    * The data definition.
@@ -85,7 +86,7 @@ public function getPluginId() {
    * {@inheritdoc}
    */
   public function getPluginDefinition() {
-    return \Drupal::typedDataManager()->getDefinition($this->definition->getDataType());
+    return $this->getTypedDataManager()->getDefinition($this->definition->getDataType());
   }
 
   /**
@@ -124,8 +125,7 @@ public function getString() {
    * {@inheritdoc}
    */
   public function getConstraints() {
-    // @todo: Add the typed data manager as proper dependency.
-    $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
+    $constraint_manager = $this->getTypedDataManager()->getValidationConstraintManager();
     $constraints = array();
     foreach ($this->definition->getConstraints() as $name => $options) {
       $constraints[] = $constraint_manager->create($name, $options);
@@ -137,8 +137,7 @@ public function getConstraints() {
    * {@inheritdoc}
    */
   public function validate() {
-    // @todo: Add the typed data manager as proper dependency.
-    return \Drupal::typedDataManager()->getValidator()->validate($this);
+    return $this->getTypedDataManager()->getValidator()->validate($this);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index 858d13d..bd9717b 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -23,7 +23,7 @@
 /**
  * Manages data type plugins.
  */
-class TypedDataManager extends DefaultPluginManager {
+class TypedDataManager extends DefaultPluginManager implements TypedDataManagerInterface {
   use DependencySerializationTrait;
 
   /**
@@ -76,22 +76,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   }
 
   /**
-   * Instantiates a typed data object.
-   *
-   * @param string $data_type
-   *   The data type, for which a typed object should be instantiated.
-   * @param array $configuration
-   *   The plugin configuration array, i.e. an array with the following keys:
-   *   - data_definition: The data definition object, i.e. an instance of
-   *     \Drupal\Core\TypedData\DataDefinitionInterface.
-   *   - name: (optional) If a property or list item is to be created, the name
-   *     of the property or the delta of the list item.
-   *   - parent: (optional) If a property or list item is to be created, the
-   *     parent typed data object implementing either the ListInterface or the
-   *     ComplexDataInterface.
-   *
-   * @return \Drupal\Core\TypedData\TypedDataInterface
-   *   The instantiated typed data object.
+   * {@inheritdoc}
    */
   public function createInstance($data_type, array $configuration = array()) {
     $data_definition = $configuration['data_definition'];
@@ -108,39 +93,13 @@ public function createInstance($data_type, array $configuration = array()) {
     if (!isset($class)) {
       throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type));
     }
-    return $class::createInstance($data_definition, $configuration['name'], $configuration['parent']);
+    $typed_data = $class::createInstance($data_definition, $configuration['name'], $configuration['parent']);
+    $typed_data->setTypedDataManager($this);
+    return $typed_data;
   }
 
   /**
-   * Creates a new typed data object instance.
-   *
-   * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
-   *   The data definition of the typed data object. For backwards-compatibility
-   *   an array representation of the data definition may be passed also.
-   * @param mixed $value
-   *   (optional) The data value. If set, it has to match one of the supported
-   *   data type format as documented for the data type classes.
-   * @param string $name
-   *   (optional) If a property or list item is to be created, the name of the
-   *   property or the delta of the list item.
-   * @param mixed $parent
-   *   (optional) If a property or list item is to be created, the parent typed
-   *   data object implementing either the ListInterface or the
-   *   ComplexDataInterface.
-   *
-   * @return \Drupal\Core\TypedData\TypedDataInterface
-   *   The instantiated typed data object.
-   *
-   * @see \Drupal::typedDataManager()
-   * @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
-   * @see \Drupal\Core\TypedData\Plugin\DataType\BinaryData
-   * @see \Drupal\Core\TypedData\Plugin\DataType\BooleanData
-   * @see \Drupal\Core\TypedData\Plugin\DataType\Date
-   * @see \Drupal\Core\TypedData\Plugin\DataType\Duration
-   * @see \Drupal\Core\TypedData\Plugin\DataType\FloatData
-   * @see \Drupal\Core\TypedData\Plugin\DataType\IntegerData
-   * @see \Drupal\Core\TypedData\Plugin\DataType\StringData
-   * @see \Drupal\Core\TypedData\Plugin\DataType\Uri
+   * {@inheritdoc}
    */
   public function create(DataDefinitionInterface $definition, $value = NULL, $name = NULL, $parent = NULL) {
     $typed_data = $this->createInstance($definition->getDataType(), array(
@@ -155,25 +114,7 @@ public function create(DataDefinitionInterface $definition, $value = NULL, $name
   }
 
   /**
-   * Creates a new data definition object.
-   *
-   * While data definitions objects may be created directly if the definition
-   * class used by a data type is known, this method allows the creation of data
-   * definitions for any given data type.
-   *
-   * E.g., if a definition for a map is to be created, the following code
-   * could be used instead of calling this method with the argument 'map':
-   * @code
-   *   $map_definition = \Drupal\Core\TypedData\MapDataDefinition::create();
-   * @endcode
-   *
-   * @param string $data_type
-   *   The data type, for which a data definition should be created.
-   *
-   * @return \Drupal\Core\TypedData\DataDefinitionInterface
-   *   A data definition for the given data type.
-   *
-   * @see \Drupal\Core\TypedData\TypedDataManager::createListDataDefinition()
+   * {@inheritdoc}
    */
   public function createDataDefinition($data_type) {
     $type_definition = $this->getDefinition($data_type);
@@ -185,15 +126,7 @@ public function createDataDefinition($data_type) {
   }
 
   /**
-   * Creates a new list data definition for items of the given data type.
-   *
-   * @param string $item_type
-   *   The item type, for which a list data definition should be created.
-   *
-   * @return \Drupal\Core\TypedData\ListDataDefinitionInterface
-   *   A list definition for items of the given data type.
-   *
-   * @see \Drupal\Core\TypedData\TypedDataManager::createDataDefinition()
+   * {@inheritdoc}
    */
   public function createListDataDefinition($item_type) {
     $type_definition = $this->getDefinition($item_type);
@@ -205,59 +138,14 @@ public function createListDataDefinition($item_type) {
   }
 
   /**
-   * Implements \Drupal\Component\Plugin\PluginManagerInterface::getInstance().
-   *
-   * @param array $options
-   *   An array of options with the following keys:
-   *   - object: The parent typed data object, implementing the
-   *     TypedDataInterface and either the ListInterface or the
-   *     ComplexDataInterface.
-   *   - property: The name of the property to instantiate, or the delta of the
-   *     the list item to instantiate.
-   *   - value: The value to set. If set, it has to match one of the supported
-   *     data type formats as documented by the data type classes.
-   *
-   * @throws \InvalidArgumentException
-   *   If the given property is not known, or the passed object does not
-   *   implement the ListInterface or the ComplexDataInterface.
-   *
-   * @return \Drupal\Core\TypedData\TypedDataInterface
-   *   The new property instance.
-   *
-   * @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
+   * {@inheritdoc}
    */
   public function getInstance(array $options) {
     return $this->getPropertyInstance($options['object'], $options['property'], $options['value']);
   }
 
   /**
-   * Get a typed data instance for a property of a given typed data object.
-   *
-   * This method will use prototyping for fast and efficient instantiation of
-   * many property objects with the same property path; e.g.,
-   * when multiple comments are used comment_body.0.value needs to be
-   * instantiated very often.
-   * Prototyping is done by the root object's data type and the given
-   * property path, i.e. all property instances having the same property path
-   * and inheriting from the same data type are prototyped.
-   *
-   * @param \Drupal\Core\TypedData\TypedDataInterface $object
-   *   The parent typed data object, implementing the TypedDataInterface and
-   *   either the ListInterface or the ComplexDataInterface.
-   * @param string $property_name
-   *   The name of the property to instantiate, or the delta of an list item.
-   * @param mixed $value
-   *   (optional) The data value. If set, it has to match one of the supported
-   *   data type formats as documented by the data type classes.
-   *
-   * @throws \InvalidArgumentException
-   *   If the given property is not known, or the passed object does not
-   *   implement the ListInterface or the ComplexDataInterface.
-   *
-   * @return \Drupal\Core\TypedData\TypedDataInterface
-   *   The new property instance.
-   *
-   * @see \Drupal\Core\TypedData\TypedDataManager::create()
+   * {@inheritdoc}
    */
   public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL) {
     // For performance, try to reuse existing prototypes instead of
@@ -325,10 +213,7 @@ public function setValidator(ValidatorInterface $validator) {
   }
 
   /**
-   * Gets the validator for validating typed data.
-   *
-   * @return \Symfony\Component\Validator\Validator\ValidatorInterface
-   *   The validator object.
+   * {@inheritdoc}
    */
   public function getValidator() {
     if (!isset($this->validator)) {
@@ -342,43 +227,21 @@ public function getValidator() {
   }
 
   /**
-   * Sets the validation constraint manager.
-   *
-   * The validation constraint manager is used to instantiate validation
-   * constraint plugins.
-   *
-   * @param \Drupal\Core\Validation\ConstraintManager
-   *   The constraint manager to set.
+   * {@inheritdoc}
    */
   public function setValidationConstraintManager(ConstraintManager $constraintManager) {
     $this->constraintManager = $constraintManager;
   }
 
   /**
-   * Gets the validation constraint manager.
-   *
-   * @return \Drupal\Core\Validation\ConstraintManager
-   *   The constraint manager.
+   * {@inheritdoc}
    */
   public function getValidationConstraintManager() {
     return $this->constraintManager;
   }
 
   /**
-   * Gets default constraints for the given data definition.
-   *
-   * This generates default constraint definitions based on the data definition;
-   * e.g. a NotNull constraint is generated if the data is defined as required.
-   * Besides that any constraints defined for the data type, i.e. below the
-   * 'constraint' key of the type's plugin definition, are taken into account.
-   *
-   * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
-   *   A data definition.
-   *
-   * @return array
-   *   An array of validation constraint definitions, keyed by constraint name.
-   *   Each constraint definition can be used for instantiating
-   *   \Symfony\Component\Validator\Constraint objects.
+   * {@inheritdoc}
    */
   public function getDefaultConstraints(DataDefinitionInterface $definition) {
     $constraints = array();
@@ -412,30 +275,7 @@ public function clearCachedDefinitions() {
   }
 
   /**
-   * Gets the canonical representation of a TypedData object.
-   *
-   * The canonical representation is typically used when data is passed on to
-   * other code components. In many use cases, the TypedData object is mostly
-   * unified adapter wrapping a primary value (e.g. a string, an entity...)
-   * which is the canonical representation that consuming code like constraint
-   * validators are really interested in. For some APIs, though, the domain
-   * object (e.g. Field API's FieldItem and FieldItemList) directly implements
-   * TypedDataInterface, and the canonical representation is thus the data
-   * object itself.
-   *
-   * When a TypedData object gets validated, for example, its canonical
-   * representation is passed on to constraint validators, which thus receive
-   * an Entity unwrapped, but a FieldItem as is.
-   *
-   * Data types specify whether their data objects need unwrapping by using the
-   * 'unwrap_for_canonical_representation' property in the data definition
-   * (defaults to TRUE).
-   *
-   * @param \Drupal\Core\TypedData\TypedDataInterface $data
-   *   The data.
-   *
-   * @return mixed
-   *   The canonical representation of the passed data.
+   * {@inheritdoc}
    */
   public function getCanonicalRepresentation(TypedDataInterface $data) {
     $data_definition = $data->getDataDefinition();
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManagerInterface.php
similarity index 50%
copy from core/lib/Drupal/Core/TypedData/TypedDataManager.php
copy to core/lib/Drupal/Core/TypedData/TypedDataManagerInterface.php
index 858d13d..8f8ff99 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManagerInterface.php
@@ -2,81 +2,23 @@
 
 /**
  * @file
- * Contains \Drupal\Core\TypedData\TypedDataManager.
+ * Contains \Drupal\Core\TypedData\TypedDataManagerInterface.
  */
 
 namespace Drupal\Core\TypedData;
 
-use Drupal\Component\Plugin\Exception\PluginException;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\DependencyInjection\ClassResolverInterface;
-use Drupal\Core\DependencyInjection\DependencySerializationTrait;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\Core\TypedData\Validation\ExecutionContextFactory;
-use Drupal\Core\TypedData\Validation\RecursiveValidator;
+use Drupal\Component\Plugin\PluginManagerInterface;
+use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Core\Validation\ConstraintManager;
-use Drupal\Core\Validation\ConstraintValidatorFactory;
-use Drupal\Core\Validation\DrupalTranslator;
 use Symfony\Component\Validator\Validator\ValidatorInterface;
 
 /**
- * Manages data type plugins.
+ * Defines an interface for typed data manager.
  */
-class TypedDataManager extends DefaultPluginManager {
-  use DependencySerializationTrait;
+interface TypedDataManagerInterface extends PluginManagerInterface, CachedDiscoveryInterface {
 
   /**
-   * The validator used for validating typed data.
-   *
-   * @var \Symfony\Component\Validator\Validator\ValidatorInterface
-   */
-  protected $validator;
-
-  /**
-   * The validation constraint manager to use for instantiating constraints.
-   *
-   * @var \Drupal\Core\Validation\ConstraintManager
-   */
-  protected $constraintManager;
-
-  /**
-   * An array of typed data property prototypes.
-   *
-   * @var array
-   */
-  protected $prototypes = array();
-
-  /**
-   * The class resolver.
-   *
-   * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
-   */
-  protected $classResolver;
-
-  /**
-   * Constructs a new TypedDataManager.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
-   *   The class resolver.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver) {
-    $this->alterInfo('data_type_info');
-    $this->setCacheBackend($cache_backend, 'typed_data_types_plugins');
-    $this->classResolver = $class_resolver;
-
-    parent::__construct('Plugin/DataType', $namespaces, $module_handler, NULL, 'Drupal\Core\TypedData\Annotation\DataType');
-  }
-
-  /**
-   * Instantiates a typed data object.
+   * {@inheritdoc}
    *
    * @param string $data_type
    *   The data type, for which a typed object should be instantiated.
@@ -93,23 +35,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
    * @return \Drupal\Core\TypedData\TypedDataInterface
    *   The instantiated typed data object.
    */
-  public function createInstance($data_type, array $configuration = array()) {
-    $data_definition = $configuration['data_definition'];
-    $type_definition = $this->getDefinition($data_type);
-
-    if (!isset($type_definition)) {
-      throw new \InvalidArgumentException("Invalid data type '$data_type' has been given");
-    }
-
-    // Allow per-data definition overrides of the used classes, i.e. take over
-    // classes specified in the type definition.
-    $class = $data_definition->getClass();
-
-    if (!isset($class)) {
-      throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $data_type));
-    }
-    return $class::createInstance($data_definition, $configuration['name'], $configuration['parent']);
-  }
+  public function createInstance($data_type, array $configuration = array());
 
   /**
    * Creates a new typed data object instance.
@@ -131,7 +57,6 @@ public function createInstance($data_type, array $configuration = array()) {
    * @return \Drupal\Core\TypedData\TypedDataInterface
    *   The instantiated typed data object.
    *
-   * @see \Drupal::typedDataManager()
    * @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
    * @see \Drupal\Core\TypedData\Plugin\DataType\BinaryData
    * @see \Drupal\Core\TypedData\Plugin\DataType\BooleanData
@@ -142,17 +67,7 @@ public function createInstance($data_type, array $configuration = array()) {
    * @see \Drupal\Core\TypedData\Plugin\DataType\StringData
    * @see \Drupal\Core\TypedData\Plugin\DataType\Uri
    */
-  public function create(DataDefinitionInterface $definition, $value = NULL, $name = NULL, $parent = NULL) {
-    $typed_data = $this->createInstance($definition->getDataType(), array(
-      'data_definition' => $definition,
-      'name' => $name,
-      'parent' => $parent,
-    ));
-    if (isset($value)) {
-      $typed_data->setValue($value, FALSE);
-    }
-    return $typed_data;
-  }
+  public function create(DataDefinitionInterface $definition, $value = NULL, $name = NULL, $parent = NULL);
 
   /**
    * Creates a new data definition object.
@@ -175,14 +90,7 @@ public function create(DataDefinitionInterface $definition, $value = NULL, $name
    *
    * @see \Drupal\Core\TypedData\TypedDataManager::createListDataDefinition()
    */
-  public function createDataDefinition($data_type) {
-    $type_definition = $this->getDefinition($data_type);
-    if (!isset($type_definition)) {
-      throw new \InvalidArgumentException("Invalid data type '$data_type' has been given");
-    }
-    $class = $type_definition['definition_class'];
-    return $class::createFromDataType($data_type);
-  }
+  public function createDataDefinition($data_type);
 
   /**
    * Creates a new list data definition for items of the given data type.
@@ -195,17 +103,10 @@ public function createDataDefinition($data_type) {
    *
    * @see \Drupal\Core\TypedData\TypedDataManager::createDataDefinition()
    */
-  public function createListDataDefinition($item_type) {
-    $type_definition = $this->getDefinition($item_type);
-    if (!isset($type_definition)) {
-      throw new \InvalidArgumentException("Invalid data type '$item_type' has been given");
-    }
-    $class = $type_definition['list_definition_class'];
-    return $class::createFromItemType($item_type);
-  }
+  public function createListDataDefinition($item_type);
 
   /**
-   * Implements \Drupal\Component\Plugin\PluginManagerInterface::getInstance().
+   * {@inheritdoc}
    *
    * @param array $options
    *   An array of options with the following keys:
@@ -226,9 +127,7 @@ public function createListDataDefinition($item_type) {
    *
    * @see \Drupal\Core\TypedData\TypedDataManager::getPropertyInstance()
    */
-  public function getInstance(array $options) {
-    return $this->getPropertyInstance($options['object'], $options['property'], $options['value']);
-  }
+  public function getInstance(array $options);
 
   /**
    * Get a typed data instance for a property of a given typed data object.
@@ -259,60 +158,15 @@ public function getInstance(array $options) {
    *
    * @see \Drupal\Core\TypedData\TypedDataManager::create()
    */
-  public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL) {
-    // For performance, try to reuse existing prototypes instead of
-    // constructing new objects when possible. A prototype is reused when
-    // creating a data object:
-    // - for a similar root object (same data type and settings),
-    // - at the same property path under that root object.
-    $root_definition = $object->getRoot()->getDataDefinition();
-    // If the root object is a list, we want to look at the data type and the
-    // settings of its item definition.
-    if ($root_definition instanceof ListDataDefinition) {
-      $root_definition = $root_definition->getItemDefinition();
-    }
+  public function getPropertyInstance(TypedDataInterface $object, $property_name, $value = NULL);
 
-    // Root data type and settings.
-    $parts[] = $root_definition->getDataType();
-    if ($settings = $root_definition->getSettings()) {
-      // Hash the settings into a string. crc32 is the fastest way to hash
-      // something for non-cryptographic purposes.
-      $parts[] = crc32(serialize($settings));
-    }
-    // Property path for the requested data object. When creating a list item,
-    // use 0 in the key as all items look the same.
-    $parts[] = $object->getPropertyPath() . '.' . (is_numeric($property_name) ? 0 : $property_name);
-    $key = implode(':', $parts);
-
-    // Create the prototype if needed.
-    if (!isset($this->prototypes[$key])) {
-      // Fetch the data definition for the child object from the parent.
-      if ($object instanceof ComplexDataInterface) {
-        $definition = $object->getDataDefinition()->getPropertyDefinition($property_name);
-      }
-      elseif ($object instanceof ListInterface) {
-        $definition = $object->getItemDefinition();
-      }
-      else {
-        throw new \InvalidArgumentException("The passed object has to either implement the ComplexDataInterface or the ListInterface.");
-      }
-      if (!$definition) {
-        throw new \InvalidArgumentException("Property $property_name is unknown.");
-      }
-      // Create the prototype without any value, but with initial parenting
-      // so that constructors can set up the objects correclty.
-      $this->prototypes[$key] = $this->create($definition, NULL, $property_name, $object);
-    }
-
-    // Clone the prototype, update its parenting information, and assign the
-    // value.
-    $property = clone $this->prototypes[$key];
-    $property->setContext($property_name, $object);
-    if (isset($value)) {
-      $property->setValue($value, FALSE);
-    }
-    return $property;
-  }
+  /**
+   * Gets the validator for validating typed data.
+   *
+   * @return \Symfony\Component\Validator\Validator\ValidatorInterface
+   *   The validator object.
+   */
+  public function getValidator();
 
   /**
    * Sets the validator for validating typed data.
@@ -320,26 +174,15 @@ public function getPropertyInstance(TypedDataInterface $object, $property_name,
    * @param \Symfony\Component\Validator\Validator\ValidatorInterface $validator
    *   The validator object to set.
    */
-  public function setValidator(ValidatorInterface $validator) {
-    $this->validator = $validator;
-  }
+  public function setValidator(ValidatorInterface $validator);
 
   /**
-   * Gets the validator for validating typed data.
+   * Gets the validation constraint manager.
    *
-   * @return \Symfony\Component\Validator\Validator\ValidatorInterface
-   *   The validator object.
+   * @return \Drupal\Core\Validation\ConstraintManager
+   *   The constraint manager.
    */
-  public function getValidator() {
-    if (!isset($this->validator)) {
-      $this->validator = new RecursiveValidator(
-        new ExecutionContextFactory(new DrupalTranslator()),
-        new ConstraintValidatorFactory($this->classResolver),
-        $this
-      );
-    }
-    return $this->validator;
-  }
+  public function getValidationConstraintManager();
 
   /**
    * Sets the validation constraint manager.
@@ -350,19 +193,7 @@ public function getValidator() {
    * @param \Drupal\Core\Validation\ConstraintManager
    *   The constraint manager to set.
    */
-  public function setValidationConstraintManager(ConstraintManager $constraintManager) {
-    $this->constraintManager = $constraintManager;
-  }
-
-  /**
-   * Gets the validation constraint manager.
-   *
-   * @return \Drupal\Core\Validation\ConstraintManager
-   *   The constraint manager.
-   */
-  public function getValidationConstraintManager() {
-    return $this->constraintManager;
-  }
+  public function setValidationConstraintManager(ConstraintManager $constraintManager);
 
   /**
    * Gets default constraints for the given data definition.
@@ -380,36 +211,7 @@ public function getValidationConstraintManager() {
    *   Each constraint definition can be used for instantiating
    *   \Symfony\Component\Validator\Constraint objects.
    */
-  public function getDefaultConstraints(DataDefinitionInterface $definition) {
-    $constraints = array();
-    $type_definition = $this->getDefinition($definition->getDataType());
-    // Auto-generate a constraint for data types implementing a primitive
-    // interface.
-    if (is_subclass_of($type_definition['class'], '\Drupal\Core\TypedData\PrimitiveInterface')) {
-      $constraints['PrimitiveType'] = array();
-    }
-    // Add in constraints specified by the data type.
-    if (isset($type_definition['constraints'])) {
-      $constraints += $type_definition['constraints'];
-    }
-    // Add the NotNull constraint for required data.
-    if ($definition->isRequired()) {
-      $constraints['NotNull'] = array();
-    }
-    // Check if the class provides allowed values.
-    if (is_subclass_of($definition->getClass(),'Drupal\Core\TypedData\OptionsProviderInterface')) {
-      $constraints['AllowedValues'] = array();
-    }
-    return $constraints;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function clearCachedDefinitions() {
-    parent::clearCachedDefinitions();
-    $this->prototypes = array();
-  }
+  public function getDefaultConstraints(DataDefinitionInterface $definition);
 
   /**
    * Gets the canonical representation of a TypedData object.
@@ -437,18 +239,6 @@ public function clearCachedDefinitions() {
    * @return mixed
    *   The canonical representation of the passed data.
    */
-  public function getCanonicalRepresentation(TypedDataInterface $data) {
-    $data_definition = $data->getDataDefinition();
-    // In case a list is passed, respect the 'wrapped' key of its data type.
-    if ($data_definition instanceof ListDataDefinitionInterface) {
-      $data_definition = $data_definition->getItemDefinition();
-    }
-    // Get the plugin definition of the used data type.
-    $type_definition = $this->getDefinition($data_definition->getDataType());
-    if (!empty($type_definition['unwrap_for_canonical_representation'])) {
-      return $data->getValue();
-    }
-    return $data;
-  }
+  public function getCanonicalRepresentation(TypedDataInterface $data);
 
 }
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataTrait.php b/core/lib/Drupal/Core/TypedData/TypedDataTrait.php
index 737a86a..b2cde54 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataTrait.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataTrait.php
@@ -15,19 +15,19 @@
   /**
    * The typed data manager used for creating the data types.
    *
-   * @var \Drupal\Core\TypedData\TypedDataManager
+   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
    */
   protected $typedDataManager;
 
   /**
    * Sets the typed data manager.
    *
-   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
    *   The typed data manager.
    *
    * @return $this
    */
-  public function setTypedDataManager(TypedDataManager $typed_data_manager) {
+  public function setTypedDataManager(TypedDataManagerInterface $typed_data_manager) {
     $this->typedDataManager = $typed_data_manager;
     return $this;
   }
@@ -35,7 +35,7 @@ public function setTypedDataManager(TypedDataManager $typed_data_manager) {
   /**
    * Gets the typed data manager.
    *
-   * @return \Drupal\Core\TypedData\TypedDataManager
+   * @return \Drupal\Core\TypedData\TypedDataManagerInterface
    *   The typed data manager.
    */
   public function getTypedDataManager() {
diff --git a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
index 81b8eeb..05fe0a0 100644
--- a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
+++ b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php
@@ -10,7 +10,7 @@
 use Drupal\Core\TypedData\ComplexDataInterface;
 use Drupal\Core\TypedData\ListInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
-use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
 use Symfony\Component\Validator\Context\ExecutionContextInterface;
@@ -64,10 +64,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface {
    *   The metadata factory.
    * @param \Symfony\Component\Validator\ConstraintValidatorFactoryInterface $validator_factory
    *   The constraint validator factory.
-   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
    *   The typed data manager.
    */
-  public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadata_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManager $typed_data_manager) {
+  public function __construct(ExecutionContextInterface $context, MetadataFactoryInterface $metadata_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManagerInterface $typed_data_manager) {
     $this->context = $context;
     $this->metadataFactory = $metadata_factory;
     $this->constraintValidatorFactory = $validator_factory;
diff --git a/core/lib/Drupal/Core/TypedData/Validation/RecursiveValidator.php b/core/lib/Drupal/Core/TypedData/Validation/RecursiveValidator.php
index c828cba..e5260f7 100644
--- a/core/lib/Drupal/Core/TypedData/Validation/RecursiveValidator.php
+++ b/core/lib/Drupal/Core/TypedData/Validation/RecursiveValidator.php
@@ -8,7 +8,7 @@
 namespace Drupal\Core\TypedData\Validation;
 
 use Drupal\Core\TypedData\TypedDataInterface;
-use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Core\TypedData\TypedDataManagerInterface;
 use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
 use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
 use Symfony\Component\Validator\Context\ExecutionContextInterface;
@@ -44,10 +44,10 @@ class RecursiveValidator implements ValidatorInterface {
    *   The factory for creating new contexts.
    * @param \Symfony\Component\Validator\ConstraintValidatorFactoryInterface $validator_factory
    *   The constraint validator factory.
-   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
    *   The typed data manager.
    */
-  public function __construct(ExecutionContextFactoryInterface $context_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManager $typed_data_manager) {
+  public function __construct(ExecutionContextFactoryInterface $context_factory, ConstraintValidatorFactoryInterface $validator_factory, TypedDataManagerInterface $typed_data_manager) {
     $this->contextFactory = $context_factory;
     $this->constraintValidatorFactory = $validator_factory;
     $this->typedDataManager = $typed_data_manager;
