 .../serialization/serialization.services.yml       |   4 +
 .../serialization/src/Normalizer/AnyNormalizer.php |  34 +++++
 .../tests/src/Kernel/AnyNormalizerTest.php         | 166 +++++++++++++++++++++
 3 files changed, 204 insertions(+)

diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml
index dca6094..aa853a2 100644
--- a/core/modules/serialization/serialization.services.yml
+++ b/core/modules/serialization/serialization.services.yml
@@ -67,6 +67,10 @@ services:
       class: Drupal\serialization\Normalizer\MarkupNormalizer
       tags:
         - { name: normalizer }
+  serializer.normalizer.any:
+    class: Drupal\serialization\Normalizer\AnyNormalizer
+    tags:
+      - { name: normalizer }
   serializer.normalizer.typed_data:
     class: Drupal\serialization\Normalizer\TypedDataNormalizer
     tags:
diff --git a/core/modules/serialization/src/Normalizer/AnyNormalizer.php b/core/modules/serialization/src/Normalizer/AnyNormalizer.php
new file mode 100644
index 0000000..a9afcb4
--- /dev/null
+++ b/core/modules/serialization/src/Normalizer/AnyNormalizer.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\serialization\Normalizer;
+
+use Drupal\Core\TypedData\Plugin\DataType\Any;
+
+/**
+ * Converts 'any' typed data objects to arrays.
+ */
+class AnyNormalizer extends NormalizerBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $supportedInterfaceOrClass = Any::class;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function normalize($object, $format = NULL, array $context = []) {
+    $this->addCacheableDependency($context, $object);
+    $value = $object->getValue();
+    // If the value is object or array, return the normalized result, object
+    // must be normalizable. Tips: 1 Typed data or traversable object are
+    // normalizable. 2 Field type with 'any' typed data property definition
+    // which stored traversable object, must convert the array value to object
+    // in setValue() to make it can be denormalized.
+    if (isset($value) && (is_object($value) || is_array($value))) {
+      $value = $this->serializer->normalize($value, $format, $context);
+    }
+    return $value;
+  }
+
+}
diff --git a/core/modules/serialization/tests/src/Kernel/AnyNormalizerTest.php b/core/modules/serialization/tests/src/Kernel/AnyNormalizerTest.php
new file mode 100644
index 0000000..8f69b08
--- /dev/null
+++ b/core/modules/serialization/tests/src/Kernel/AnyNormalizerTest.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace Drupal\Tests\serialization\Kernel;
+
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\serialization\Normalizer\AnyNormalizer
+ * @group typedData
+ */
+class AnyNormalizerTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'serialization'];
+
+  /**
+   * The serializer type.
+   *
+   * @var \Symfony\Component\Serializer\Serializer
+   */
+  protected $serializer;
+
+  /**
+   * The typeDataManager.
+   *
+   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
+   */
+  protected $typedDataManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->serializer = \Drupal::service('serializer');
+    $this->typedDataManager = \Drupal::typedDataManager();
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with basic string stored.
+   */
+  public function testNormalizeBase() {
+    $typed_data = $this->buildDataBasicString();
+    $this->assertSame('test', $this->serializer->normalize($typed_data, 'json'));
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with traversable object stored.
+   */
+  public function testNormalizeWithObjectTraversable() {
+    $typed_data = $this->buildDataWithObjectTraversable();
+    $this->assertSame([
+      'property1' => 'value1',
+      'property2' => 'value2',
+    ], $this->serializer->normalize($typed_data));
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with typed data stored.
+   */
+  public function testNormalizeWithTypedData() {
+    $typed_data = $this->buildDataWithTypedData();
+    $this->assertSame('test', $this->serializer->normalize($typed_data));
+  }
+
+  /**
+   * Tests normalizing 'any' typed data on more complex situation.
+   */
+  public function testNormalizeComplex() {
+    $typed_data = $this->buildDataComplex();
+    $this->assertSame([
+      'key1' => 'test1',
+      'key2' => 'test2',
+      'key3' => [
+        'property1' => 'value1',
+        'property2' => 'value2',
+      ],
+    ], $this->serializer->normalize($typed_data));
+  }
+
+  /**
+   * Builds example 'any' typed data with basic string stored.
+   */
+  protected function buildDataBasicString() {
+    $typed_data = $this->typedDataManager->create(
+      DataDefinition::create('any'),
+      'test',
+      'test name'
+    );
+    return $typed_data;
+  }
+
+  /**
+   * Builds example 'any' typed data with traversable object stored.
+   */
+  protected function buildDataWithObjectTraversable() {
+    $typed_data = $this->typedDataManager->create(
+      DataDefinition::create('any'),
+      new ObjectTraversable(),
+      'test name'
+    );
+    return $typed_data;
+  }
+
+  /**
+   * Builds example 'any' typed data with typed data stored.
+   */
+  protected function buildDataWithTypedData() {
+    $typed_data_string = $this->typedDataManager->create(
+      DataDefinition::create('string'),
+      'test',
+      'typed data string'
+    );
+    $typed_data_any = $this->typedDataManager->create(
+      DataDefinition::create('any'),
+      $typed_data_string,
+      'typed data any'
+    );
+    return $typed_data_any;
+  }
+
+  /**
+   * Builds example 'any' typed data with more complex data stored.
+   */
+  protected function buildDataComplex() {
+    $typed_data_string = $this->typedDataManager->create(
+      DataDefinition::create('string'),
+      'test2',
+      'typed data string'
+    );
+    $objectTraversable = new ObjectTraversable();
+    $value = [
+      'key1' => 'test1',
+      'key2' => $typed_data_string,
+      'key3' => $objectTraversable,
+    ];
+    $typed_data_any = $this->typedDataManager->create(
+      DataDefinition::create('any'),
+      $value,
+      'typed data any'
+    );
+    return $typed_data_any;
+  }
+
+}
+
+/**
+ * Build a traversable object.
+ */
+class ObjectTraversable implements \IteratorAggregate {
+
+  public $property1 = "value1";
+
+  public $property2 = "value2";
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    return new \ArrayIterator($this);
+  }
+
+}
