How to get the JSON/array value property name for a field instance? Given a Drupal\Core\Field\BaseFieldDefinition  how do you get whether the value is stored by target_id, or value or uri or color or ....

it seems getMainPropertyName() is what i'm looking, for but it returns null for the majority of fields. in my case it's only returning target_id or value for for created, status, and entity_id.
I just tested using a variety of field types, and it seems to work OK for me. Here's the code I used for testing:

$node = \Drupal\node\Entity\Node::load($nid);

print $node-&gt;get('field_test')-&gt;getFieldDefinition()-&gt;getFieldStorageDefinition()-&gt;getMainPropertyName();
print $node-&gt;get('field_test_image')-&gt;getFieldDefinition()-&gt;getFieldStorageDefinition()-&gt;getMainPropertyName();
print $node-&gt;get('field_test_link')-&gt;getFieldDefinition()-&gt;getFieldStorageDefinition()-&gt;getMainPropertyName();
print $node-&gt;get('field_test_email')-&gt;getFieldDefinition()-&gt;getFieldStorageDefinition()-&gt;getMainPropertyName();


This returns value, target_id, uri and value as one would have expected. What kind of fields are giving you trouble? How do you get you BaseFieldDefinition class? What kind of entity are they connected to?

I notice that the Views way of getting the property name is also pretty pragmatic:

// EntityField.php line 1111
if ($main_property_name = $field_item-&gt;mainPropertyName()) {
  $values[] = $field_item-&gt;{$main_property_name};
}
else {
  $values[] = $field_item-&gt;value;
}


Clearly it's not completely unexpected to have this method return null.