diff --git a/core/core.services.yml b/core/core.services.yml
index 59e8a6f19890a9bed816dbed2bdf85b5614c6156..d8bac8f4be9084ba443e5d0b778f331d8ee77932 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -132,7 +132,9 @@ services:
     class: Drupal\Core\Config\InstallStorage
   config.typed:
     class: Drupal\Core\Config\TypedConfigManager
-    arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery']
+    arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler']
+    tags:
+      - { name: plugin_manager_cache_clear }
   context.handler:
     class: Drupal\Core\Plugin\Context\ContextHandler
     arguments: ['@typed_data_manager']
diff --git a/core/lib/Drupal/Core/Config/Schema/ConfigSchemaDiscovery.php b/core/lib/Drupal/Core/Config/Schema/ConfigSchemaDiscovery.php
new file mode 100644
index 0000000000000000000000000000000000000000..53330ec9f4e126dca5d6d4094e92b2ff9a825371
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Schema/ConfigSchemaDiscovery.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\Schema\ConfigSchemaDiscovery.
+ */
+
+namespace Drupal\Core\Config\Schema;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\Component\Plugin\Discovery\DiscoveryTrait;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Allows YAML files to define config schema types.
+ */
+class ConfigSchemaDiscovery implements DiscoveryInterface {
+
+  use DiscoveryTrait;
+
+  /**
+   * A storage instance for reading configuration schema data.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $schemaStorage;
+
+  /**
+   * Constructs a ConfigSchemaDiscovery object.
+   *
+   * @param $schema_storage
+   *   The storage object to use for reading schema data.
+   */
+  function __construct(StorageInterface $schema_storage) {
+    $this->schemaStorage = $schema_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinitions() {
+    $definitions = array();
+    foreach ($this->schemaStorage->readMultiple($this->schemaStorage->listAll()) as $schema) {
+      foreach ($schema as $type => $definition) {
+        $definitions[$type] = $definition;
+      }
+    }
+    return $definitions;
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index ba3f3530df2911cd11b164d54a751d2e69c2f7a9..c025a2079a6e5b373d9a82d3db86d12b9244cbf7 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -9,6 +9,8 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\Schema\ConfigSchemaDiscovery;
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\TypedData\TypedDataManager;
 
 /**
@@ -16,13 +18,6 @@
  */
 class TypedConfigManager extends TypedDataManager implements TypedConfigManagerInterface {
 
-  /**
-   * The cache ID for the definitions.
-   *
-   * @var string
-   */
-  const CACHE_ID = 'typed_config_definitions';
-
   /**
    * A storage instance for reading configuration data.
    *
@@ -44,13 +39,6 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
    */
   protected $definitions;
 
-  /**
-   * Cache backend for the definitions.
-   *
-   * @var \Drupal\Core\Cache\CacheBackendInterface
-   */
-  protected $cache;
-
   /**
    * Creates a new typed configuration manager.
    *
@@ -61,10 +49,13 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend to use for caching the definitions.
    */
-  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache) {
+  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler) {
     $this->configStorage = $configStorage;
     $this->schemaStorage = $schemaStorage;
-    $this->cache = $cache;
+    $this->setCacheBackend($cache, 'typed_config_definitions');
+    $this->discovery = new ConfigSchemaDiscovery($schemaStorage);
+    $this->alterInfo('config_schema_info');
+    $this->moduleHandler = $module_handler;
   }
 
   /**
@@ -147,34 +138,12 @@ public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) {
     );
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefinitions() {
-    if (!isset($this->definitions)) {
-      if ($cache = $this->cache->get($this::CACHE_ID)) {
-        $this->definitions = $cache->data;
-      }
-      else {
-        $this->definitions = array();
-        foreach ($this->schemaStorage->readMultiple($this->schemaStorage->listAll()) as $schema) {
-          foreach ($schema as $type => $definition) {
-            $this->definitions[$type] = $definition;
-          }
-        }
-        $this->cache->set($this::CACHE_ID, $this->definitions);
-      }
-    }
-    return $this->definitions;
-  }
-
   /**
    * {@inheritdoc}
    */
   public function clearCachedDefinitions() {
-    $this->definitions = NULL;
     $this->schemaStorage->reset();
-    $this->cache->delete($this::CACHE_ID);
+    parent::clearCachedDefinitions();
   }
 
   /**
diff --git a/core/modules/config/src/Tests/DefaultConfigTest.php b/core/modules/config/src/Tests/DefaultConfigTest.php
index 3edbc7c73071b184e70fa22d35f7c74a0ee05b34..48805612e7faffe3e630afd6b8c3b89555badcff 100644
--- a/core/modules/config/src/Tests/DefaultConfigTest.php
+++ b/core/modules/config/src/Tests/DefaultConfigTest.php
@@ -37,7 +37,8 @@ public function testDefaultConfig() {
     $typed_config = new TypedConfigManager(
       \Drupal::service('config.storage'),
       new TestInstallStorage(InstallStorage::CONFIG_SCHEMA_DIRECTORY),
-      \Drupal::service('cache.discovery')
+      \Drupal::service('cache.discovery'),
+      \Drupal::service('module_handler')
     );
 
     // Create a configuration storage with access to default configuration in
diff --git a/core/modules/config_translation/config_translation.api.php b/core/modules/config_translation/config_translation.api.php
index a7db1857e02e10fc9e987dd1e70ed6b9f8a7e83c..27c89b199fc9f272fa2afef041340e3891f5b092 100644
--- a/core/modules/config_translation/config_translation.api.php
+++ b/core/modules/config_translation/config_translation.api.php
@@ -88,25 +88,6 @@ function hook_config_translation_info_alter(&$info) {
   $info['system.site_information_settings']['names'][] = 'example.site.setting';
 }
 
-/**
- * Alter config typed data definitions.
- *
- * Used to automatically generate translation forms, you can alter the typed
- * data types representing each configuration schema type to change default
- * labels or form element renderers.
- *
- * @param $definitions
- *   Associative array of configuration type definitions keyed by schema type
- *   names. The elements are themselves array with information about the type.
- */
-function hook_config_translation_type_info_alter(&$definitions) {
-  // Enhance the text and date type definitions with classes to generate proper
-  // form elements in ConfigTranslationFormBase. Other translatable types will
-  // appear as a one line textfield.
-  $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea';
-  $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat';
-}
-
 /**
  * @} End of "addtogroup hooks".
  */
diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module
index b1289312bdb0ff8a8b3a46591cb2a520531c9b1c..b0565b7a4e65396592e501b1aa23cedb9b2769ae 100644
--- a/core/modules/config_translation/config_translation.module
+++ b/core/modules/config_translation/config_translation.module
@@ -192,9 +192,9 @@ function config_translation_entity_operation(EntityInterface $entity) {
 }
 
 /**
- * Implements hook_config_translation_type_info_alter().
+ * Implements hook_config_schema_info_alter().
  */
-function config_translation_config_translation_type_info_alter(&$definitions) {
+function config_translation_config_schema_info_alter(&$definitions) {
   // Enhance the text and date type definitions with classes to generate proper
   // form elements in ConfigTranslationFormBase. Other translatable types will
   // appear as a one line textfield.
diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
index 528158e9b221a73c617453c51a81aacf3a561b98..f3f769d57a49095d35963ceab57f9d982f298725 100644
--- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
@@ -49,13 +49,6 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
    */
   protected $localeStorage;
 
-  /**
-   * The module handler to invoke the alter hook.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
   /**
    * The mapper for configuration translation.
    *
@@ -100,14 +93,11 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
    *   The configuration mapper manager.
    * @param \Drupal\locale\StringStorageInterface $locale_storage
    *   The translation storage object.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler to invoke the alter hook.
    */
-  public function __construct(TypedConfigManagerInterface $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ModuleHandlerInterface $module_handler, ConfigurableLanguageManagerInterface $language_manager) {
+  public function __construct(TypedConfigManagerInterface $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ConfigurableLanguageManagerInterface $language_manager) {
     $this->typedConfigManager = $typed_config_manager;
     $this->configMapperManager = $config_mapper_manager;
     $this->localeStorage = $locale_storage;
-    $this->moduleHandler = $module_handler;
     $this->languageManager = $language_manager;
   }
 
@@ -119,7 +109,6 @@ public static function create(ContainerInterface $container) {
       $container->get('config.typed'),
       $container->get('plugin.manager.config_translation.mapper'),
       $container->get('locale.storage'),
-      $container->get('module_handler'),
       $container->get('language_manager')
     );
   }
@@ -312,13 +301,6 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
       else {
         $definition = $element->getDataDefinition();
 
-        // Invoke hook_config_translation_type_info_alter() implementations to
-        // alter the configuration types.
-        $definitions = array(
-          $definition['type'] => &$definition,
-        );
-        $this->moduleHandler->alter('config_translation_type_info', $definitions);
-
         // Create form element only for translatable items.
         if (!isset($definition['translatable']) || !isset($definition['type'])) {
           continue;
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 14771543c082cbb9897dc544a28728e20c68f136..b50698f3b3d6b7ffcb895a55be2804194b7289bd 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -2837,6 +2837,33 @@ function hook_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\Config
   }
 }
 
+/**
+ * Alter config typed data definitions.
+ *
+ * For example you can alter the typed data types representing each
+ * configuration schema type to change default labels or form element renderers
+ * used for configuration translation.
+ *
+ * It is strongly advised not to use this hook to add new data types or to
+ * change the structure of existing ones. Keep in mind that there are tools
+ * that may use the configuration schema for static analysis of configuration
+ * files, like the string extractor for the localization system. Such systems
+ * won't work with dynamically defined configuration schemas.
+ *
+ * For adding new data types use configuration schema YAML files instead.
+ *
+ * @param $definitions
+ *   Associative array of configuration type definitions keyed by schema type
+ *   names. The elements are themselves array with information about the type.
+ */
+function hook_config_schema_info_alter(&$definitions) {
+  // Enhance the text and date type definitions with classes to generate proper
+  // form elements in ConfigTranslationFormBase. Other translatable types will
+  // appear as a one line textfield.
+  $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea';
+  $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat';
+}
+
 /**
  * @} End of "addtogroup hooks".
  */