diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
index 4ab69cb98ef2557169d43d5ad1c9453e559fad7f..3df078a06bfa0bec46f260c93ba164352f5949b9 100644
--- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php
@@ -186,7 +186,7 @@ protected function init() {
           // @todo Remove handling of 'type' in https://www.drupal.org/node/2799641.
           if (!isset($options['region']) && !empty($options['type']) && $options['type'] === 'hidden') {
             $options['region'] = 'hidden';
-            @trigger_error("Specifying 'type' => 'hidden' is deprecated, use 'region' => 'hidden' instead.", E_USER_DEPRECATED);
+            @trigger_error("Support for using 'type' => 'hidden' in a component is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use 'region' => 'hidden' instead. See https://www.drupal.org/node/2801513", E_USER_DEPRECATED);
           }
 
           if (!empty($options['region']) && $options['region'] === 'hidden') {
@@ -253,7 +253,13 @@ public function id() {
   public function preSave(EntityStorageInterface $storage) {
     // Ensure that a region is set on each component.
     foreach ($this->getComponents() as $name => $component) {
-      $this->handleHiddenType($name, $component);
+      // @todo Remove this BC layer in Drupal 9.
+      // @see https://www.drupal.org/project/drupal/issues/2799641
+      if (!isset($component['region']) && isset($component['type']) && $component['type'] === 'hidden') {
+        @trigger_error("Support for using 'type' => 'hidden' in a component is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use 'region' => 'hidden' instead. See https://www.drupal.org/node/2801513", E_USER_DEPRECATED);
+        $this->removeComponent($name);
+      }
+
       // Ensure that a region is set.
       if (isset($this->content[$name]) && !isset($component['region'])) {
         // Directly set the component to bypass other changes in setComponent().
@@ -269,16 +275,21 @@ public function preSave(EntityStorageInterface $storage) {
   /**
    * Handles a component type of 'hidden'.
    *
-   * @deprecated This method exists only for backwards compatibility.
-   *
-   * @todo Remove this in https://www.drupal.org/node/2799641.
+   * The logic of this method has been duplicated inline in the preSave()
+   * method so that this method may remain deprecated and trigger an error.
    *
    * @param string $name
    *   The name of the component.
    * @param array $component
    *   The component array.
+   *
+   * @deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. No
+   *   replacement is provided.
+   *
+   * @see https://www.drupal.org/node/2801513
    */
   protected function handleHiddenType($name, array $component) {
+    @trigger_error(__METHOD__ . ' is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. No replacement is provided. See https://www.drupal.org/node/2801513', E_USER_DEPRECATED);
     if (!isset($component['region']) && isset($component['type']) && $component['type'] === 'hidden') {
       $this->removeComponent($name);
     }
diff --git a/core/modules/field/migrations/d7_field_formatter_settings.yml b/core/modules/field/migrations/d7_field_formatter_settings.yml
index b4580a235603b283f7fc86654549606dfb6cb995..f41575fdc8747ce2d358956644f165032ea148ff 100644
--- a/core/modules/field/migrations/d7_field_formatter_settings.yml
+++ b/core/modules/field/migrations/d7_field_formatter_settings.yml
@@ -80,6 +80,12 @@ process:
     -
       plugin: skip_on_empty
       method: row
+  hidden:
+    plugin: static_map
+    source: "@options/type"
+    map:
+      hidden: true
+    default_value: false
   "options/settings":
     plugin: default_value
     source: 'formatter/settings'
diff --git a/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php
index e0d450eb4e5d19149f43898bc3abebd36c24ef88..230493db80b4b8819b3656ac945b47d76df6b9d3 100644
--- a/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php
+++ b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php
@@ -29,9 +29,11 @@ public function testPreSave() {
       'status' => TRUE,
       'content' => [
         'foo' => ['type' => 'visible'],
-        'bar' => ['type' => 'hidden'],
         'name' => ['type' => 'hidden', 'region' => 'content'],
       ],
+      'hidden' => [
+        'bar' => TRUE,
+      ],
     ]);
 
     $expected = [
@@ -54,11 +56,10 @@ public function testPreSave() {
         'foo' => [
           'type' => 'visible',
         ],
-        'bar' => [
-          'type' => 'hidden',
-        ],
       ],
-      'hidden' => [],
+      'hidden' => [
+        'bar' => TRUE,
+      ],
     ];
     $this->assertEntityValues($expected, $entity_display->toArray());
 
@@ -76,10 +77,6 @@ public function testPreSave() {
     $expected['third_party_settings']['entity_test'] = ['foo' => 'bar'];
     // The visible field is assigned the default region.
     $expected['content']['foo']['region'] = 'content';
-    // The hidden field is removed from the list of visible fields, and marked
-    // as hidden.
-    unset($expected['content']['bar']);
-    $expected['hidden'] = ['bar' => TRUE];
 
     $this->assertEntityValues($expected, $entity_display->toArray());
 
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
index 258301f6fe9da0eab6d7bc742a0569299d08c4f4..7237d2413e5a44a28ff07636beb795b44872c17c 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php
@@ -41,14 +41,13 @@ public function testPreSave() {
       'status' => TRUE,
       'content' => [
         'foo' => ['type' => 'visible'],
-        'bar' => ['type' => 'hidden'],
+        'bar' => ['region' => 'hidden'],
         'name' => ['type' => 'hidden', 'region' => 'content'],
       ],
     ]);
 
     // Ensure that no region is set on the component.
     $this->assertArrayNotHasKey('region', $entity_display->getComponent('foo'));
-    $this->assertArrayNotHasKey('region', $entity_display->getComponent('bar'));
 
     // Ensure that a region is set on the component after saving.
     $entity_display->save();
@@ -58,8 +57,9 @@ public function testPreSave() {
     $this->assertArrayHasKey('region', $component);
     $this->assertSame('content', $component['region']);
 
-    // The component with a hidden type has been removed.
-    $this->assertNull($entity_display->getComponent('bar'));
+    $component = $entity_display->getComponent('bar');
+    $this->assertArrayHasKey('region', $component);
+    $this->assertSame('hidden', $component['region']);
 
     // The component with a valid region and hidden type is unchanged.
     $component = $entity_display->getComponent('name');
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/LegacyEntityDisplayBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/LegacyEntityDisplayBaseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7bec4976eb38d6601e102f5b79914602e17d7bd
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Entity/LegacyEntityDisplayBaseTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Entity;
+
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests Deprecated EntityDisplayBase functionality.
+ *
+ * @group Entity
+ * @group legacy
+ */
+class LegacyEntityDisplayBaseTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'entity_test',
+    'entity_test_third_party',
+    'field',
+    'system',
+    'comment',
+    'user',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('comment');
+    $this->installEntitySchema('entity_test');
+    $this->installSchema('user', ['users_data']);
+  }
+
+  /**
+   * Tests legacy handling of 'type' => 'hidden'.
+   *
+   * @group legacy
+   *
+   * @expectedDeprecation Support for using 'type' => 'hidden' in a component is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use 'region' => 'hidden' instead. See https://www.drupal.org/node/2801513
+   */
+  public function testLegacyPreSave() {
+    $entity_display = EntityViewDisplay::create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+      'status' => TRUE,
+      'content' => [
+        'foo' => ['type' => 'visible'],
+        'bar' => ['type' => 'hidden'],
+        'name' => ['type' => 'hidden', 'region' => 'content'],
+      ],
+    ]);
+
+    // Ensure that no region is set on the component.
+    $this->assertArrayNotHasKey('region', $entity_display->getComponent('foo'));
+    $this->assertArrayNotHasKey('region', $entity_display->getComponent('bar'));
+
+    // Ensure that a region is set on the component after saving.
+    $entity_display->save();
+
+    // The component with a visible type has been assigned a region.
+    $component = $entity_display->getComponent('foo');
+    $this->assertArrayHasKey('region', $component);
+    $this->assertSame('content', $component['region']);
+
+    // The component with a hidden type has been removed.
+    $this->assertNull($entity_display->getComponent('bar'));
+
+    // The component with a valid region and hidden type is unchanged.
+    $component = $entity_display->getComponent('name');
+    $this->assertArrayHasKey('region', $component);
+    $this->assertSame('content', $component['region']);
+  }
+
+  /**
+   * Tests the deprecated ::handleHiddenType() method.
+   *
+   * @expectedDeprecation Drupal\Core\Entity\EntityDisplayBase::handleHiddenType is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. No replacement is provided. See https://www.drupal.org/node/2801513
+   */
+  public function testHandleHiddenType() {
+    $entity_display = EntityViewDisplay::create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+      'status' => TRUE,
+      'content' => [
+        'foo' => ['type' => 'visible'],
+        'bar' => ['type' => 'hidden'],
+        'name' => ['type' => 'hidden', 'region' => 'content'],
+      ],
+    ]);
+    $method = new \ReflectionMethod($entity_display, 'handleHiddenType');
+    $method->setAccessible(TRUE);
+    $this->assertSame(['type' => 'hidden'], $entity_display->getComponent('bar'));
+    $method->invoke($entity_display, 'bar', ['type' => 'hidden']);
+    $this->assertNull($entity_display->getComponent('bar'));
+  }
+
+}