Drupal 8.9.x still has the options_allowed_values() (a function implemented in the Options module). If the field uses a selection, check box, or a radio button widget, you could use the following code. The same function is still implemented in Drupal 9.3.x, the latest Drupal version under development, at the time I am posting this answer.
$field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('entity', 'bundle'); if (isset($field_definitions['field'])) { $allowed_options = options_allowed_values($field_definitions['field']->getFieldStorageDefinition()); } Replace 'entity' with the entity type ID (for example, 'node' for nodes), 'bundle' with the bundle machine name (for example, 'article' for Article nodes), and 'field' with the field machine name.
Keep in mind that this code requires the Options module; the module using the code I shown should declare its dependency from it.
Using options_allowed_values() has the benefit that, if the field has a function returning the allowed values, that function is called. The following is the code used by options_allowed_values() to achieve that.
if (!isset($allowed_values[$cache_id])) { $function = $definition->getSetting('allowed_values_function'); $cacheable = TRUE; if (!empty($function)) { $values = $function($definition, $entity, $cacheable); } else { $values = $definition->getSetting('allowed_values'); } if ($cacheable) { $allowed_values[$cache_id] = $values; } else { return $values; } } Using options_allowed_values() also allows to cache the allowed values. In this way, calling options_allowed_values() for the same field (and same entity type) multiple times has a minimal impact on performance.
options_allowed_values() is still defined also in Drupal 9.xDrupal 9.x, Drupal 10.x, and Drupal 10.xDrupal 11.x.