diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
index a95c14b30e..f8ddb6d987 100644
--- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
+++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\TypedData\Plugin\DataType;
 
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Core\TypedData\MapDataDefinition;
 use Drupal\Core\TypedData\TypedData;
 use Drupal\Core\TypedData\ComplexDataInterface;
 
@@ -155,11 +157,40 @@ protected function writePropertyValue($property_name, $value) {
    */
   public function getProperties($include_computed = FALSE) {
     $properties = [];
+
     foreach ($this->definition->getPropertyDefinitions() as $name => $definition) {
       if ($include_computed || !$definition->isComputed()) {
         $properties[$name] = $this->get($name);
       }
     }
+
+    // If module creator send an array to map dataType and don't define setPropertyDefinition,
+    // Auto creating the PropertyDefinition so that it can be normalized
+    if (empty($properties) && get_class($this->getDataDefinition()) == 'Drupal\Core\TypedData\MapDataDefinition') {
+      $values = $this->values;
+      if (is_array($values)) {
+        foreach ($values as $key => $value) {
+          if (!empty($value) && is_array($value)) {
+            $properties[$key] = \Drupal::typedDataManager()->create(
+              MapDataDefinition::create(),
+              $value,
+              $key
+            );
+          }
+          else {
+            $properties[$key] = \Drupal::typedDataManager()->create(
+            // Give array's value a DataType,So that drupal can find which normalizer to be used to normalize it
+            // Because we don't know the type of the value,so we use 'any',
+            // If you don't want to use 'any',Please define it by yourself use setPropertyDefinition
+              DataDefinition::create('any'),
+              $value,
+              $key
+            );
+          }
+        };
+      }
+    }
+
     return $properties;
   }
 
diff --git a/core/tests/Drupal/Tests/Core/TypedData/MapDataNormalizeTest.php b/core/tests/Drupal/Tests/Core/TypedData/MapDataNormalizeTest.php
new file mode 100644
index 0000000000..7362558268
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/TypedData/MapDataNormalizeTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\Tests\Core\TypedData;
+
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Core\TypedData\MapDataDefinition;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @group typedData
+ */
+class MapDataNormalizeTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+
+  public static $modules = ['system', 'serialization'];
+
+  /**
+   * The serializer type.
+   */
+  protected $serializer;
+
+  /**
+   * The typeDataManager.
+   */
+  protected $typedDataManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->serializer = \Drupal::service('serializer');
+    $this->typedDataManager = \Drupal::typedDataManager();
+  }
+
+  /**
+   * Test whether map data can be normalized
+   */
+  public function testMapNormalize() {
+    $typed_data = $this->buildExampleTypedData();
+    $data = $this->serializer->normalize($typed_data, 'json');
+    $expect_value = [
+      'key1' => 'value1',
+      'key2' => 'value2',
+    ];
+    $this->assertEquals($expect_value, $data);
+  }
+
+  /**
+   * Test whether map data with properties can be normalized
+   */
+  public function testMapWithPropertiesNormalize() {
+    $typed_data = $this->buildExampleTypedDataWithProperties();
+    $data = $this->serializer->normalize($typed_data, 'json');
+    $expect_value = [
+      'key1' => 'value1',
+      'key2' => 'value2',
+    ];
+    $this->assertEquals($expect_value, $data);
+  }
+
+  /**
+   * Builds some example type data object with no properties.
+   */
+  protected function buildExampleTypedData() {
+    $tree = [
+      'key1' => 'value1',
+      'key2' => 'value2',
+    ];
+    $map_data_definition = MapDataDefinition::create();
+    $typed_data = $this->typedDataManager->create(
+      $map_data_definition,
+      $tree,
+      'test name'
+    );
+    return $typed_data;
+  }
+
+  /**
+   * Builds some example type data object with properties.
+   */
+  protected function buildExampleTypedDataWithProperties() {
+    $tree = [
+      'key1' => 'value1',
+      'key2' => 'value2',
+    ];
+    $map_data_definition = MapDataDefinition::create();
+    foreach (array_keys($tree) as $property_name) {
+      $map_data_definition->setPropertyDefinition($property_name, DataDefinition::create('string'));
+    }
+    $typed_data = $this->typedDataManager->create(
+      $map_data_definition,
+      $tree,
+      'test name'
+    );
+
+    return $typed_data;
+  }
+
+}
