diff --git a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
index 5eb0faf..f22fef2 100644
--- a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
+++ b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
@@ -16,6 +16,7 @@
  *
  * @ConfigEntityType(
  *   id = "date_format",
+ *   interface = "Drupal\Core\Datetime\DateFormatInterface",
  *   label = @Translation("Date format"),
  *   handlers = {
  *     "access" = "Drupal\system\DateFormatAccessControlHandler",
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
index f512022..afe39e0 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
@@ -18,6 +18,7 @@
  *
  * @ConfigEntityType(
  *   id = "entity_form_display",
+ *   interface = "Drupal\Core\Entity\Display\EntityFormDisplayInterface",
  *   label = @Translation("Entity form display"),
  *   entity_keys = {
  *     "id" = "id",
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php
index 7f8371a..66936a1 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php
@@ -29,6 +29,7 @@
  *
  * @ConfigEntityType(
  *   id = "entity_form_mode",
+ *   interface = "Drupal\Core\Entity\EntityFormModeInterface",
  *   label = @Translation("Form mode"),
  *   entity_keys = {
  *     "id" = "id",
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
index 9a73268..e0d8bf4 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
@@ -18,6 +18,7 @@
  *
  * @ConfigEntityType(
  *   id = "entity_view_display",
+ *   interface = "Drupal\Core\Entity\Display\EntityViewDisplayInterface",
  *   label = @Translation("Entity view display"),
  *   entity_keys = {
  *     "id" = "id",
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php
index 80a3875..373ae89 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php
@@ -31,6 +31,7 @@
  *
  * @ConfigEntityType(
  *   id = "entity_view_mode",
+ *   interface = "Drupal\Core\Entity\EntityViewModeInterface",
  *   label = @Translation("View mode"),
  *   entity_keys = {
  *     "id" = "id",
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 5ea863d..a9672ba 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -80,6 +80,15 @@ class EntityType implements EntityTypeInterface {
   protected $originalClass;
 
   /**
+   * The interface entities of this type must implement.
+   *
+   * @var string|null
+   *   A fully qualified interface name or NULL when the data does not
+   *   necessarily have to implement a particular interface.
+   */
+  protected $interface;
+
+  /**
    * An array of handlers.
    *
    * @var array
@@ -352,6 +361,20 @@ public function setClass($class) {
   /**
    * {@inheritdoc}
    */
+  public function getInterface() {
+    return $this->interface;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setInterface($interface) {
+    $this->interface = $interface;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isSubclassOf($class) {
     return is_subclass_of($this->getClass(), $class);
   }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index f8237a5..ab05aed 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -87,6 +87,24 @@ public function getClass();
   public function getOriginalClass();
 
   /**
+   * Returns the interface of the entity type.
+   *
+   * @return string|null
+   *   A fully qualified interface name or NULL when the data does not
+   *   necessarily have to implement a particular interface.
+   */
+  public function getInterface();
+
+  /**
+   * Sets the interface of the entity type.
+   *
+   * @param string|null $interface
+   *   A fully qualified interface name or NULL when the data does not
+   *   necessarily have to implement a particular interface.
+   */
+  public function setInterface($interface);
+
+  /**
    * Returns an array of entity keys.
    *
    * @return array
diff --git a/core/lib/Drupal/Core/TypedData/Annotation/DataType.php b/core/lib/Drupal/Core/TypedData/Annotation/DataType.php
index 332c3ed..3b6b79a 100644
--- a/core/lib/Drupal/Core/TypedData/Annotation/DataType.php
+++ b/core/lib/Drupal/Core/TypedData/Annotation/DataType.php
@@ -106,4 +106,13 @@ class DataType extends Plugin {
    */
   public $constraints;
 
+  /**
+   * The interface data of this type must implement.
+   *
+   * @var string|null
+   *   A fully qualified interface name or NULL when the data does not
+   *   necessarily have to implement a particular interface.
+   */
+  public $interface;
+
 }
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index 9206d23..64d15c8 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -396,4 +396,63 @@ public function clearCachedDefinitions() {
     $this->prototypes = array();
   }
 
+  /**
+   * Gets the data type plugin ID for raw data.
+   *
+   * @param mixed @param
+   *
+   * @return string|null
+   */
+  public function getPluginIdForData($data) {
+    if (!is_object($data)) {
+      return NULL;
+    }
+
+    // Keys are interface names and values are plugin IDs.
+    $possible_plugins = array();
+    foreach ($this->getDefinitions() as $plugin_id => $definition) {
+      if (isset($definition['interface']) && is_subclass_of($data, $definition['interface'])) {
+        $possible_plugins[$definition['interface']] = $plugin_id;
+      }
+    }
+    $interface = $this->filterInterfacesForData(array_keys($possible_plugins));
+    return $interface ? $possible_plugins[$interface] : NULL;
+  }
+
+  /**
+   * Finds the most specific interface an object implements.
+   *
+   * @param string[] $interfaces
+   *   An array of fully qualified interface names.
+   *
+   * @return string|null
+   *   A fully qualified interface name or NULL if no single interface could be
+   *   found.
+   */
+  protected function filterInterfacesForData(array $interfaces) {
+    $interfaces = array_unique($interfaces);
+    $count = count($interfaces);
+    foreach ($interfaces as $i_a => $interface_a) {
+      foreach ($interfaces as $i_b => $interface_b) {
+        if (is_subclass_of($interface_b, $interface_a)) {
+          unset($interfaces[$i_a]);
+        }
+        elseif (is_subclass_of($interface_a, $interface_b)) {
+          unset($interfaces[$i_b]);
+        }
+      }
+    }
+    if ($count > 1) {
+      if (count($interfaces) !== $count) {
+        return $this->filterInterfacesForData($interfaces);
+      }
+      else {
+        return NULL;
+      }
+    }
+    else {
+      return reset($interfaces);
+    }
+  }
+
 }
diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php
index 6532f36..f3a5766 100644
--- a/core/modules/aggregator/src/Entity/Feed.php
+++ b/core/modules/aggregator/src/Entity/Feed.php
@@ -19,6 +19,7 @@
  *
  * @ContentEntityType(
  *   id = "aggregator_feed",
+ *   interface = "Drupal\aggregator\FeedInterface",
  *   label = @Translation("Aggregator feed"),
  *   handlers = {
  *     "storage" = "Drupal\aggregator\FeedStorage",
diff --git a/core/modules/aggregator/src/Entity/Item.php b/core/modules/aggregator/src/Entity/Item.php
index 09eed9b..74f990e 100644
--- a/core/modules/aggregator/src/Entity/Item.php
+++ b/core/modules/aggregator/src/Entity/Item.php
@@ -20,6 +20,7 @@
  *
  * @ContentEntityType(
  *   id = "aggregator_item",
+ *   interface = "Drupal\aggregator\ItemInterface",
  *   label = @Translation("Aggregator feed item"),
  *   handlers = {
  *     "storage" = "Drupal\aggregator\ItemStorage",
diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php
index 20d70a4..ead6fd9 100644
--- a/core/modules/block/src/Entity/Block.php
+++ b/core/modules/block/src/Entity/Block.php
@@ -20,6 +20,7 @@
  *
  * @ConfigEntityType(
  *   id = "block",
+ *   interface = "Drupal\block\BlockInterface",
  *   label = @Translation("Block"),
  *   handlers = {
  *     "access" = "Drupal\block\BlockAccessControlHandler",
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index e2320bd..b026f3f 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -18,6 +18,7 @@
  *
  * @ContentEntityType(
  *   id = "block_content",
+ *   interface = "Drupal\block_content\BlockContentInterface",
  *   label = @Translation("Custom Block"),
  *   bundle_label = @Translation("Custom Block type"),
  *   handlers = {
diff --git a/core/modules/block_content/src/Entity/BlockContentType.php b/core/modules/block_content/src/Entity/BlockContentType.php
index 007ebfb..333f41b 100644
--- a/core/modules/block_content/src/Entity/BlockContentType.php
+++ b/core/modules/block_content/src/Entity/BlockContentType.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "block_content_type",
+ *   interface = "Drupal\block_content\BlockContentTypeInterface",
  *   label = @Translation("Custom block type"),
  *   handlers = {
  *     "form" = {
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index 57c7287..c494b19 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -21,6 +21,7 @@
  *
  * @ContentEntityType(
  *   id = "comment",
+ *   interface = "Drupal\comment\CommentInterface",
  *   label = @Translation("Comment"),
  *   bundle_label = @Translation("Content type"),
  *   handlers = {
diff --git a/core/modules/comment/src/Entity/CommentType.php b/core/modules/comment/src/Entity/CommentType.php
index 3a1b3a8..4bc2962 100644
--- a/core/modules/comment/src/Entity/CommentType.php
+++ b/core/modules/comment/src/Entity/CommentType.php
@@ -16,6 +16,7 @@
  *
  * @ConfigEntityType(
  *   id = "comment_type",
+ *   interface = "Drupal\comment\CommentTypeInterface",
  *   label = @Translation("Comment type"),
  *   handlers = {
  *     "form" = {
diff --git a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
index b022cc6..8e4219c 100644
--- a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
+++ b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "config_test",
+ *   interface = "Drupal\config_test\ConfigTestInterface",
  *   label = @Translation("Test configuration"),
  *   handlers = {
  *     "storage" = "Drupal\config_test\ConfigTestStorage",
diff --git a/core/modules/contact/src/Entity/ContactForm.php b/core/modules/contact/src/Entity/ContactForm.php
index 02abc13..c07e0b6 100644
--- a/core/modules/contact/src/Entity/ContactForm.php
+++ b/core/modules/contact/src/Entity/ContactForm.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "contact_form",
+ *   interface = "Drupal\contact\ContactFormInterface",
  *   label = @Translation("Contact form"),
  *   handlers = {
  *     "access" = "Drupal\contact\ContactFormAccessControlHandler",
diff --git a/core/modules/contact/src/Entity/Message.php b/core/modules/contact/src/Entity/Message.php
index 20be2e8..1a96684 100644
--- a/core/modules/contact/src/Entity/Message.php
+++ b/core/modules/contact/src/Entity/Message.php
@@ -17,6 +17,7 @@
  *
  * @ContentEntityType(
  *   id = "contact_message",
+ *   interface = "Drupal\contact\MessageInterface",
  *   label = @Translation("Contact message"),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\ContentEntityNullStorage",
diff --git a/core/modules/editor/src/Entity/Editor.php b/core/modules/editor/src/Entity/Editor.php
index 29f7350..ff67be7 100644
--- a/core/modules/editor/src/Entity/Editor.php
+++ b/core/modules/editor/src/Entity/Editor.php
@@ -15,6 +15,7 @@
  *
  * @ConfigEntityType(
  *   id = "editor",
+ *   interface = "Drupal\editor\EditorInterface",
  *   label = @Translation("Text Editor"),
  *   entity_keys = {
  *     "id" = "format"
diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php
index 2e5f329..a5379bc 100644
--- a/core/modules/field/src/Entity/FieldConfig.php
+++ b/core/modules/field/src/Entity/FieldConfig.php
@@ -19,6 +19,7 @@
  *
  * @ConfigEntityType(
  *   id = "field_config",
+ *   interface = "Drupal\field\FieldConfigInterface",
  *   label = @Translation("Field"),
  *   handlers = {
  *     "access" = "Drupal\field\FieldConfigAccessControlHandler",
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index 29794c7..998fa10 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -23,6 +23,7 @@
  * @ConfigEntityType(
  *   id = "field_storage_config",
  *   label = @Translation("Field storage"),
+ *   interface = "Drupal\field\FieldStorageConfigInterface",
  *   handlers = {
  *     "storage" = "Drupal\field\FieldStorageConfigStorage"
  *   },
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index b21a182..a262cbd 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -20,6 +20,7 @@
  *
  * @ContentEntityType(
  *   id = "file",
+ *   interface = "Drupal\file\FileInterface",
  *   label = @Translation("File"),
  *   handlers = {
  *     "storage" = "Drupal\file\FileStorage",
diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php
index 1f38428..9f5d80e 100644
--- a/core/modules/filter/src/Entity/FilterFormat.php
+++ b/core/modules/filter/src/Entity/FilterFormat.php
@@ -19,6 +19,7 @@
  *
  * @ConfigEntityType(
  *   id = "filter_format",
+ *   interface = "Drupal\filter\FilterFormatInterface",
  *   label = @Translation("Text format"),
  *   handlers = {
  *     "form" = {
diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php
index 752dc1e..428c038 100644
--- a/core/modules/image/src/Entity/ImageStyle.php
+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -26,6 +26,7 @@
  *
  * @ConfigEntityType(
  *   id = "image_style",
+ *   interface = "Drupal\image\ImageStyleInterface",
  *   label = @Translation("Image style"),
  *   handlers = {
  *     "form" = {
diff --git a/core/modules/language/src/Entity/ConfigurableLanguage.php b/core/modules/language/src/Entity/ConfigurableLanguage.php
index 1235b8a..a890cc3 100644
--- a/core/modules/language/src/Entity/ConfigurableLanguage.php
+++ b/core/modules/language/src/Entity/ConfigurableLanguage.php
@@ -20,6 +20,7 @@
  *
  * @ConfigEntityType(
  *   id = "configurable_language",
+ *   interface = "Drupal\language\ConfigurableLanguageInterface",
  *   label = @Translation("Language"),
  *   handlers = {
  *     "list_builder" = "Drupal\language\LanguageListBuilder",
diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
index ec719c2..abb8a64 100644
--- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
+++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
@@ -19,6 +19,7 @@
  *
  * @ContentEntityType(
  *   id = "menu_link_content",
+ *   interface = "Drupal\menu_link_content\MenuLinkContentInterface",
  *   label = @Translation("Custom menu link"),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php
index 9fb93b7..76b17d3 100644
--- a/core/modules/migrate/src/Entity/Migration.php
+++ b/core/modules/migrate/src/Entity/Migration.php
@@ -22,6 +22,7 @@
  *
  * @ConfigEntityType(
  *   id = "migration",
+ *   interface = "Drupal\migrate\Entity\MigrationInterface",
  *   label = @Translation("Migration"),
  *   module = "migrate",
  *   handlers = {
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index b5bb8f8..434f819 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -21,6 +21,7 @@
  *
  * @ContentEntityType(
  *   id = "node",
+ *   interface = "Drupal\node\NodeInterface",
  *   label = @Translation("Content"),
  *   bundle_label = @Translation("Content type"),
  *   handlers = {
diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php
index 73e1202..4e5259f 100644
--- a/core/modules/node/src/Entity/NodeType.php
+++ b/core/modules/node/src/Entity/NodeType.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "node_type",
+ *   interface = "Drupal\node\NodeTypeInterface",
  *   label = @Translation("Content type"),
  *   handlers = {
  *     "access" = "Drupal\node\NodeTypeAccessControlHandler",
diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php
index b842547..c9dd9c2 100644
--- a/core/modules/rdf/src/Entity/RdfMapping.php
+++ b/core/modules/rdf/src/Entity/RdfMapping.php
@@ -16,6 +16,7 @@
  *
  * @ConfigEntityType(
  *   id = "rdf_mapping",
+ *   interface = "Drupal\rdf\RdfMappingInterface",
  *   label = @Translation("RDF mapping"),
  *   config_prefix = "mapping",
  *   entity_keys = {
diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
index 3e8440e..fd604f2 100644
--- a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
+++ b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
@@ -15,6 +15,7 @@
  *
  * @ConfigEntityType(
  *   id = "responsive_image_mapping",
+ *   interface = "Drupal\responsive_image\ResponsiveImageMappingInterface",
  *   label = @Translation("Responsive image mapping"),
  *   handlers = {
  *     "list_builder" = "Drupal\responsive_image\ResponsiveImageMappingListBuilder",
diff --git a/core/modules/search/src/Entity/SearchPage.php b/core/modules/search/src/Entity/SearchPage.php
index 28aa0f8..cecd390 100644
--- a/core/modules/search/src/Entity/SearchPage.php
+++ b/core/modules/search/src/Entity/SearchPage.php
@@ -21,6 +21,7 @@
  *
  * @ConfigEntityType(
  *   id = "search_page",
+ *   interface = "Drupal\search\SearchPageInterface",
  *   label = @Translation("Search page"),
  *   handlers = {
  *     "access" = "Drupal\search\SearchPageAccessControlHandler",
diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php
index 75d5b22..f1c7567 100644
--- a/core/modules/shortcut/src/Entity/Shortcut.php
+++ b/core/modules/shortcut/src/Entity/Shortcut.php
@@ -21,6 +21,7 @@
  *
  * @ContentEntityType(
  *   id = "shortcut",
+ *   interface = "Drupal\shortcut\ShortcutInterface",
  *   label = @Translation("Shortcut link"),
  *   handlers = {
  *     "access" = "Drupal\shortcut\ShortcutAccessControlHandler",
diff --git a/core/modules/shortcut/src/Entity/ShortcutSet.php b/core/modules/shortcut/src/Entity/ShortcutSet.php
index da60378..55f1ba9 100644
--- a/core/modules/shortcut/src/Entity/ShortcutSet.php
+++ b/core/modules/shortcut/src/Entity/ShortcutSet.php
@@ -16,6 +16,7 @@
  *
  * @ConfigEntityType(
  *   id = "shortcut_set",
+ *   interface = "Drupal\shortcut\ShortcutSetInterface",
  *   label = @Translation("Shortcut set"),
  *   handlers = {
  *     "storage" = "Drupal\shortcut\ShortcutSetStorage",
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index b9f60fe..e8887b1 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -278,6 +278,8 @@
  *   content entity type that uses bundles, the 'bundle_label' annotation gives
  *   the human-readable name to use for a bundle of this entity type (for
  *   example, "Content type" for the Node entity).
+ * - The 'interface' annotation refers to an interface which the class should
+ *   implement.
  * - The annotation will refer to several controller classes, which you will
  *   also need to define:
  *   - list_builder: Define a class that extends
diff --git a/core/modules/system/src/Entity/Action.php b/core/modules/system/src/Entity/Action.php
index e48f335..1770a20 100644
--- a/core/modules/system/src/Entity/Action.php
+++ b/core/modules/system/src/Entity/Action.php
@@ -19,6 +19,7 @@
  *
  * @ConfigEntityType(
  *   id = "action",
+ *   interface = "Drupal\system\ActionConfigEntityInterface",
  *   label = @Translation("Action"),
  *   admin_permission = "administer actions",
  *   entity_keys = {
diff --git a/core/modules/system/src/Entity/Menu.php b/core/modules/system/src/Entity/Menu.php
index d44b698..e7763a8 100644
--- a/core/modules/system/src/Entity/Menu.php
+++ b/core/modules/system/src/Entity/Menu.php
@@ -16,6 +16,7 @@
  *
  * @ConfigEntityType(
  *   id = "menu",
+ *   interface = "Drupal\system\MenuInterface",
  *   label = @Translation("Menu"),
  *   handlers = {
  *     "access" = "Drupal\system\MenuAccessControlHandler"
diff --git a/core/modules/system/tests/Drupal/system/Tests/TypedData/TypedDataManagerUnitTest.php b/core/modules/system/tests/Drupal/system/Tests/TypedData/TypedDataManagerUnitTest.php
new file mode 100644
index 0000000..efae583
--- /dev/null
+++ b/core/modules/system/tests/Drupal/system/Tests/TypedData/TypedDataManagerUnitTest.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\TypedData\TypedDataManagerUnitTest.
+ */
+
+namespace Drupal\system\Tests\TypedData;
+
+use Drupal\Core\TypedData\TypedDataManager;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass Drupal\Core\TypedData\TypedDataManager
+ * @group Typed Data API
+ */
+class TypedDataManagerUnitTest extends UnitTestCase {
+
+  /**
+   * The cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $cache;
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  /**
+   * The typed data manager under test.
+   *
+   * @var \Drupal\Core\TypedData\TypedDataManager
+   */
+  protected $typedDataManager;
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->cache = $this->getMock('\Drupal\Core\Cache\CacheBackendInterface');
+
+    $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
+
+    $namespaces = new \ArrayObject();
+
+    $this->typedDataManager = new TypedDataManager($namespaces, $this->cache, $this->moduleHandler);
+  }
+
+  /**
+   * Tests getPluginIdForData().
+   *
+   * @covers ::getPluginIdForData
+   * @covers ::filterInterfacesForData
+   */
+  public function testGetPluginIdForData() {
+    $definitions = array(
+      $this->randomMachineName() => array(
+        'interface' => '\Drupal\Core\Entity\EntityInterface',
+      ),
+      'content' => array(
+        'interface' => '\Drupal\Core\Entity\ContentEntityInterface',
+      ),
+      $this->randomMachineName() => array(
+        'interface' => '\Drupal\Core\Config\Entity\ConfigEntityInterface',
+      ),
+    );
+
+    $data = $this->getMock('\Drupal\Core\Entity\ContentEntityInterface');
+
+    $this->cache->expects($this->atLeastOnce())
+      ->method('get')
+      ->with('typed_data_types_plugins')
+      ->willReturn((object) array(
+        'data' => $definitions,
+      ));
+
+    $this->assertSame('content', $this->typedDataManager->getPluginIdForData($data));
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php
index ed213e3..784df17 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php
@@ -15,6 +15,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_base_field_display",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity - base field display"),
  *   handlers = {
  *     "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultAccess.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultAccess.php
index 239250f..d20599b 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultAccess.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultAccess.php
@@ -12,6 +12,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_default_access",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity with default access"),
  *   base_table = "entity_test",
  *   entity_keys = {
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php
index 13189c2..2b3fedb 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestDefaultValue.php
@@ -15,6 +15,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_default_value",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity for default values"),
  *   base_table = "entity_test_default_value",
  *   entity_keys = {
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestFieldOverride.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestFieldOverride.php
index 7632125..4bec153 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestFieldOverride.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestFieldOverride.php
@@ -14,6 +14,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_field_override",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity field overrides"),
  *   base_table = "entity_test_field_override",
  *   entity_keys = {
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabel.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabel.php
index b392795..64a9ee1 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabel.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabel.php
@@ -12,6 +12,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_label",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Entity Test label"),
  *   handlers = {
  *     "view_builder" = "Drupal\entity_test\EntityTestViewBuilder"
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabelCallback.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabelCallback.php
index 1088114..e9075b1 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabelCallback.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestLabelCallback.php
@@ -12,6 +12,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_label_callback",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Entity test label callback"),
  *   persistent_cache = FALSE,
  *   base_table = "entity_test",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMul.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMul.php
index 402936f..49ff2d3 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMul.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMul.php
@@ -16,6 +16,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_mul",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity - data table"),
  *   handlers = {
  *     "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
index b5fc86f..699b337 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php
@@ -16,6 +16,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_mulrev",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity - revisions and data table"),
  *   handlers = {
  *     "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoId.php
index a29c1e2..5c46410 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoId.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoId.php
@@ -12,6 +12,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_no_id",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Entity Test without id"),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\ContentEntityNullStorage",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoLabel.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoLabel.php
index 5ad3ba7..833e082 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoLabel.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestNoLabel.php
@@ -12,6 +12,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_no_label",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Entity Test without label"),
  *   persistent_cache = FALSE,
  *   base_table = "entity_test",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
index 3b40ed9..c41debd 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestRev.php
@@ -16,6 +16,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_rev",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity - revisions"),
  *   handlers = {
  *     "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
index 9d74938..72a7576 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
@@ -14,6 +14,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_string_id",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity with string_id"),
  *   handlers = {
  *     "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
index 9e792c7..67eb93d 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
@@ -17,6 +17,7 @@
  *
  * @ContentEntityType(
  *   id = "entity_test_update",
+ *   interface = "Drupal\Core\Entity\ContentEntityInterface",
  *   label = @Translation("Test entity update"),
  *   handlers = {
  *     "storage_schema" = "Drupal\entity_test\EntityTestStorageSchema"
diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php
index caebc53..7ec419d 100644
--- a/core/modules/taxonomy/src/Entity/Term.php
+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -18,6 +18,7 @@
  *
  * @ContentEntityType(
  *   id = "taxonomy_term",
+ *   interface = "Drupal\taxonomy\TermInterface",
  *   label = @Translation("Taxonomy term"),
  *   bundle_label = @Translation("Vocabulary"),
  *   handlers = {
diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php
index e650551..1816fc8 100644
--- a/core/modules/taxonomy/src/Entity/Vocabulary.php
+++ b/core/modules/taxonomy/src/Entity/Vocabulary.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "taxonomy_vocabulary",
+ *   interface = "Drupal\taxonomy\VocabularyInterface",
  *   label = @Translation("Taxonomy vocabulary"),
  *   handlers = {
  *     "storage" = "Drupal\taxonomy\VocabularyStorage",
diff --git a/core/modules/tour/src/Entity/Tour.php b/core/modules/tour/src/Entity/Tour.php
index 55b94f1..bfdf7af 100644
--- a/core/modules/tour/src/Entity/Tour.php
+++ b/core/modules/tour/src/Entity/Tour.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "tour",
+ *   interface = "Drupal\tour\TourInterface",
  *   label = @Translation("Tour"),
  *   handlers = {
  *     "view_builder" = "Drupal\tour\TourViewBuilder"
diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php
index cad0530..558d595 100644
--- a/core/modules/user/src/Entity/Role.php
+++ b/core/modules/user/src/Entity/Role.php
@@ -17,6 +17,7 @@
  *
  * @ConfigEntityType(
  *   id = "user_role",
+ *   interface = "Drupal\user\RoleInterface",
  *   label = @Translation("Role"),
  *   handlers = {
  *     "storage" = "Drupal\user\RoleStorage",
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 6bb533c..8c75a0f 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -22,6 +22,7 @@
  *
  * @ContentEntityType(
  *   id = "user",
+ *   interface = "Drupal\user\UserInterface",
  *   label = @Translation("User"),
  *   handlers = {
  *     "storage" = "Drupal\user\UserStorage",
diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index ea3664e..3bba506 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -18,6 +18,7 @@
  *
  * @ConfigEntityType(
  *   id = "view",
+ *   interface = "Drupal\views\ViewStorageInterface",
  *   label = @Translation("View"),
  *   handlers = {
  *     "access" = "Drupal\views\ViewAccessControlHandler"
