diff --git a/core/lib/Drupal/Core/Render/Element/Weight.php b/core/lib/Drupal/Core/Render/Element/Weight.php
index 649de315fd72c9dec980d80827ff879405ddd1b7..029c9e4a4975c40a0eeed91d397562a0b8d774f3 100644
--- a/core/lib/Drupal/Core/Render/Element/Weight.php
+++ b/core/lib/Drupal/Core/Render/Element/Weight.php
@@ -45,16 +45,16 @@ public function getInfo() {
   }
 
   /**
-   * Expands a weight element into a select element.
+   * Expands a weight element into a select/number element.
    */
   public static function processWeight(&$element, FormStateInterface $form_state, &$complete_form) {
+    // If the number of options is small enough, use a select field. Otherwise,
+    // use a number field.
+    $type = $element['#delta'] <= \Drupal::config('system.site')->get('weight_select_max') ? 'select' : 'number';
+    $element = array_merge($element, \Drupal::service('element_info')->getInfo($type));
     $element['#is_weight'] = TRUE;
 
-    $element_info_manager = \Drupal::service('element_info');
-    // If the number of options is small enough, use a select field.
-    $max_elements = \Drupal::config('system.site')->get('weight_select_max');
-    if ($element['#delta'] <= $max_elements) {
-      $element['#type'] = 'select';
+    if ($type === 'select') {
       $weights = [];
       for ($n = (-1 * $element['#delta']); $n <= $element['#delta']; $n++) {
         $weights[$n] = $n;
@@ -65,14 +65,10 @@ public static function processWeight(&$element, FormStateInterface $form_state,
         ksort($weights);
       }
       $element['#options'] = $weights;
-      $element += $element_info_manager->getInfo('select');
     }
-    // Otherwise, use a text field.
     else {
-      $element['#type'] = 'number';
       // Use a field big enough to fit most weights.
       $element['#size'] = 10;
-      $element += $element_info_manager->getInfo('number');
     }
 
     return $element;
diff --git a/core/modules/system/tests/modules/element_info_test/element_info_test.info.yml b/core/modules/system/tests/modules/element_info_test/element_info_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9e43148ee610038e9459d9f960a56dd9fd2bded2
--- /dev/null
+++ b/core/modules/system/tests/modules/element_info_test/element_info_test.info.yml
@@ -0,0 +1,5 @@
+name: 'Element info test'
+type: module
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/element_info_test/element_info_test.module b/core/modules/system/tests/modules/element_info_test/element_info_test.module
new file mode 100644
index 0000000000000000000000000000000000000000..58ebc889e2a063ab1fc1483f68d353b03b9b9b63
--- /dev/null
+++ b/core/modules/system/tests/modules/element_info_test/element_info_test.module
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Element info test.
+ */
+
+/**
+ * Implements hook_element_info_alter().
+ */
+function element_info_test_element_info_alter(array &$info) {
+  $info['number'] += ['#pre_render' => []];
+  /* @see \Drupal\KernelTests\Core\Render\Element\WeightTest::testProcessWeightSelectMax() */
+  $info['number']['#pre_render'][] = 'element_info_test_element_pre_render';
+}
+
+/**
+ * {@inheritdoc}
+ *
+ * @see \Drupal\KernelTests\Core\Render\Element\WeightTest::testProcessWeightSelectMax()
+ */
+function element_info_test_element_pre_render(array $element) {
+  return $element;
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/WeightTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/WeightTest.php
index 123c5e6521451b0a41910fffe5d2be626f0a2cb8..b44b98cf12833f27dbd3df4cfe7ea84279abadae 100644
--- a/core/tests/Drupal/KernelTests/Core/Render/Element/WeightTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Render/Element/WeightTest.php
@@ -3,6 +3,8 @@
 namespace Drupal\KernelTests\Core\Render\Element;
 
 use Drupal\Core\Form\FormState;
+use Drupal\Core\Render\Element\Number;
+use Drupal\Core\Render\Element\Select;
 use Drupal\Core\Render\Element\Weight;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -15,7 +17,7 @@ class WeightTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['system'];
+  protected static $modules = ['system', 'element_info_test'];
 
   /**
    * {@inheritdoc}
@@ -49,4 +51,76 @@ public function testProcessWeight() {
     );
   }
 
+  /**
+   * Test transformation from "select" to "number" for MAX_DELTA + 1.
+   *
+   * @throws \Exception
+   *
+   * @covers ::processWeight
+   */
+  public function testProcessWeightSelectMax() {
+    $form_state = new FormState();
+    $definition = [
+      '#type' => 'weight',
+      '#delta' => $this->container
+        ->get('config.factory')
+        ->get('system.site')
+        ->get('weight_select_max'),
+      // Expected by the "doBuildForm()" method of "form_builder" service.
+      '#parents' => [],
+    ];
+
+    $assert = function ($type, array $element, array $expected) use ($form_state) {
+      // Pretend we have a form to trigger the "#process" callbacks.
+      $element = $this->container
+        ->get('form_builder')
+        ->doBuildForm(__FUNCTION__, $element, $form_state);
+
+      $expected['#type'] = $type;
+
+      foreach ($expected as $property => $value) {
+        static::assertSame($value, $element[$property]);
+      }
+
+      return $element;
+    };
+
+    // When the "#delta" is less or equal to maximum the "weight" must be
+    // rendered as a "select".
+    $select = $definition;
+    $assert('select', $select, [
+      '#process' => [
+        [Select::class, 'processSelect'],
+        [Select::class, 'processAjaxForm'],
+      ],
+      '#pre_render' => [
+        [Select::class, 'preRenderSelect'],
+      ],
+    ]);
+
+    $number = $definition;
+    // Increase "#delta" in order to start rendering "number" elements
+    // instead of "select".
+    $number['#delta']++;
+    // The "number" element definition has the "#pre_render" declaration by
+    // default. The "hook_element_info_alter()" allows to modify the definition
+    // of an element. We must be sure the standard "#pre_render" callbacks
+    // are presented (unless explicitly removed) even in a case when the array
+    // is modified by the alter hook.
+    $assert('number', $number, [
+      '#process' => [
+        [Number::class, 'processAjaxForm'],
+      ],
+      '#element_validate' => [
+        [Number::class, 'validateNumber'],
+      ],
+      '#pre_render' => [
+        [Number::class, 'preRenderNumber'],
+        // The custom callback is appended.
+        /* @see element_info_test_element_info_alter() */
+        'element_info_test_element_pre_render',
+      ],
+    ]);
+  }
+
 }