diff --git a/core/modules/rest/tests/modules/rest_test/src/Plugin/Field/FieldType/TestAnyItem.php b/core/modules/rest/tests/modules/rest_test/src/Plugin/Field/FieldType/TestAnyItem.php
new file mode 100644
index 0000000000..60b7482b86
--- /dev/null
+++ b/core/modules/rest/tests/modules/rest_test/src/Plugin/Field/FieldType/TestAnyItem.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Drupal\rest_test\Plugin\Field\FieldType;
+
+use Drupal\Core\Field\FieldItemBase;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\rest_test\TraversableObject;
+
+/**
+ * Plugin implementation of the 'test_field_any' field type.
+ *
+ * @FieldType(
+ *   id = "test_field_any",
+ *   label = @Translation("test field any"),
+ *   description = @Translation("Field with 'any' property definition."),
+ * )
+ */
+class TestAnyItem extends FieldItemBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
+    $properties['value'] = DataDefinition::create('any')
+      ->setLabel(t('Value'))
+      ->setRequired(TRUE);
+
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setValue($values, $notify = TRUE) {
+    if (is_array($values)) {
+      // The property definition causes the object to be in 'value' key.
+      $values = reset($values);
+    }
+    // Use for denormalization.
+    if (is_array($values)) {
+      $values = new TraversableObject($values);
+    }
+    if (!$values instanceof TraversableObject) {
+      $values = NULL;
+    }
+    parent::setValue($values, $notify);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldStorageDefinitionInterface $field_definition) {
+    return [
+      'columns' => [
+        'value' => [
+          'description' => 'The object item value.',
+          'type' => 'blob',
+          'not null' => TRUE,
+          'serialize' => TRUE,
+        ],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/rest/tests/modules/rest_test/src/TraversableObject.php b/core/modules/rest/tests/modules/rest_test/src/TraversableObject.php
new file mode 100644
index 0000000000..196314b68c
--- /dev/null
+++ b/core/modules/rest/tests/modules/rest_test/src/TraversableObject.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\rest_test;
+
+/**
+ * Build a traversable object.
+ */
+class TraversableObject implements \IteratorAggregate {
+
+  protected $property1;
+
+  protected $property2;
+
+  /**
+   * Constructor.
+   */
+  public function __construct(array $definition) {
+    $this->property1 = $definition['property1'];
+    $this->property2 = $definition['property2'];
+  }
+
+  /**
+   * Convert to array.
+   */
+  public function toArray() {
+    return [
+      'property1' => $this->property1,
+      'property2' => $this->property2,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    return new \ArrayIterator($this->toArray());
+  }
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestAnyTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestAnyTest.php
new file mode 100644
index 0000000000..1da987650c
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestAnyTest.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
+
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\rest_test\TraversableObject;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * Tests the serialization of field with 'any' property which store object.
+ *
+ * @group rest
+ */
+class EntityTestAnyTest extends EntityTestResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * The object value to be stored into field.
+   *
+   * @var object
+   */
+  protected $object;
+
+  /**
+   * Field_test_any test field name.
+   *
+   * @var string
+   */
+  protected static $fieldName = 'field_test_any';
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->object = new TraversableObject(
+      [
+        'property1' => 'value1',
+        'property2' => 'value2',
+      ]
+    );
+
+    FieldStorageConfig::create([
+      'field_name' => static::$fieldName,
+      'type' => 'test_field_any',
+      'entity_type' => static::$entityTypeId,
+    ])
+      ->save();
+
+    FieldConfig::create([
+      'field_name' => static::$fieldName,
+      'entity_type' => static::$entityTypeId,
+      'bundle' => $this->entity->bundle(),
+    ])
+      ->save();
+
+    // Reload entity so that it has the new field.
+    $this->entity = $this->entityStorage->load($this->entity->id());
+    $this->entity->set(static::$fieldName, ['value' => $this->object]);
+    $this->entity->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $entity_test = EntityTest::create([
+      'name' => 'Llama',
+      'type' => static::$entityTypeId,
+      static::$fieldName => $this->object,
+    ]);
+    $entity_test->setOwnerId(0);
+    $entity_test->save();
+
+    return $entity_test;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return parent::getExpectedNormalizedEntity() + [
+      static::$fieldName => [
+        [
+          'value' => $this->entity->get(static::$fieldName)->value->toArray(),
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return parent::getNormalizedPostEntity() + [
+      static::$fieldName => [
+        [
+          'value' => $this->object->toArray(),
+        ],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml
index dca6094787..aa853a2f9b 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 0000000000..2c923c7e5e
--- /dev/null
+++ b/core/modules/serialization/src/Normalizer/AnyNormalizer.php
@@ -0,0 +1,36 @@
+<?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, continue normalize it, object must be
+    // normalizable. Traversable object is one of the object which can be
+    // normalized, field type with typed data 'any' property definition which
+    // stored the traversable object is advised to convert posted data to object
+    // in setValue(), so that data can be denormalized automatically without
+    // writing custom code to convert data to object when using machine readable
+    // APIs.
+    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 0000000000..7756711535
--- /dev/null
+++ b/core/modules/serialization/tests/src/Kernel/AnyNormalizerTest.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Drupal\Tests\serialization\Kernel;
+
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\serialization\Normalizer\AnyNormalizer
+ * @group typedData
+ */
+class AnyNormalizerTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'serialization', 'entity_test', 'user'];
+
+  /**
+   * 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();
+    $this->installEntitySchema('entity_test');
+    $this->installEntitySchema('user');
+  }
+
+  /**
+   * 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 testNormalizeTraversableObject() {
+    $typed_data = $this->buildDataTraversableObject();
+    $this->assertSame([
+      'property1' => 'value1',
+      'property2' => 'value2',
+    ], $this->serializer->normalize($typed_data));
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with typed data stored.
+   */
+  public function testNormalizeTypedData() {
+    $typed_data = $this->buildDataTypedData();
+    $this->assertSame('test', $this->serializer->normalize($typed_data));
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with entity stored.
+   */
+  public function testNormalizeEntity() {
+    $entity = EntityTest::create(['name' => $this->randomString()]);
+    $entity->save();
+    $normalized = $this->serializer->normalize($entity);
+    $this->assertSame($entity->getName(), $normalized['name'][0]['value']);
+  }
+
+  /**
+   * Tests normalizing 'any' typed data with non-normalizable object stored.
+   */
+  public function testNormalizeNonNormalizableObject() {
+    $this->setExpectedException(\UnexpectedValueException::class);
+    $object = $this->buildDataNonNormalizableObject();
+    $this->serializer->normalize($object);
+  }
+
+  /**
+   * 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 buildDataTraversableObject() {
+    $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 buildDataTypedData() {
+    $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 non-normalizable object stored.
+   */
+  protected function buildDataNonNormalizableObject() {
+    $typed_data = $this->typedDataManager->create(
+      DataDefinition::create('any'),
+      new Object(),
+      'test name'
+    );
+    return $typed_data;
+  }
+
+  /**
+   * 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 non-normalizable object.
+ */
+class Object {
+
+  public $property1 = "value1";
+
+  public $property2 = "value2";
+
+}
+
+/**
+ * Build a traversable object.
+ */
+class ObjectTraversable extends Object implements \IteratorAggregate {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    return new \ArrayIterator($this);
+  }
+
+}
