Entity reference in custom field type
EntityReferenceItem is more complicated than just the "entity" DataReferenceDefinition.

It has a DataReferenceDefinition for "target_id" as well.

I solved a similar issue by extending EntityReferenceItem.

Then you can get the entity from the parent definition, which is a bit long and complex and then just add your custom fields on top:

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);

    $properties['street'] = DataDefinition::create('string')
      -&gt;setLabel(new TranslatableMarkup('Title'));

    $properties['city'] = DataDefinition::create('string')
      -&gt;setLabel(new TranslatableMarkup('Title'));

    return $properties;
  }


Here's the code I used to add one text field to an EntityReferenceItem:

namespace Drupal\mymodule\Plugin\Field\FieldType;

use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Component\Utility\Random;

/**
 * Defines the 'entity_reference' entity field type.
 *
 * Supported settings (below the definition's 'settings' key) are:
 * - target_type: The entity type to reference. Required.
 *
 * @FieldType(
 *   id = "entity_reference_with_title",
 *   label = @Translation("Entity reference with title"),
 *   description = @Translation("An entity field containing an entity reference and a text field."),
 *   category = @Translation("Custom"),
 *   default_widget = "entity_reference_with_title_autocomplete",
 *   default_formatter = "entity_reference_with_title_entity_view",
 *   list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList",
 * )
 */
class EntityReferenceWithTitle extends EntityReferenceItem {

  /**
   * {@inheritdoc}
   */
  public static function defaultStorageSettings() {
    return array(
      'target_type' =&gt; \Drupal::moduleHandler()-&gt;moduleExists('node') ? 'node' : 'user',
      'title' =&gt; '',
    ) + parent::defaultStorageSettings();
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultFieldSettings() {
    return array(
      'handler' =&gt; 'default',
      'handler_settings' =&gt; array(),
    ) + parent::defaultFieldSettings();
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);

    $properties['title'] = DataDefinition::create('string')
      -&gt;setLabel(new TranslatableMarkup('Title'));

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public static function mainPropertyName() {
    return 'target_id';
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {

    $schema = parent::schema($field_definition);

    $schema['columns'] = array(
      'title' =&gt; array(
        'type' =&gt; 'varchar',
        'length' =&gt; 255,
      ),
      'target_id' =&gt; $schema['columns']['target_id'],
    );

    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public function getConstraints() {
    $constraints = FieldItemBase::getConstraints();
    // Remove the 'AllowedValuesConstraint' validation constraint because entity
    // reference fields already use the 'ValidReference' constraint.
    foreach ($constraints as $key =&gt; $constraint) {
      if ($constraint instanceof AllowedValuesConstraint) {
        unset($constraints[$key]);
      }
    }
    return $constraints;
  }

  /**
   * {@inheritdoc}
   */
  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
    $manager = \Drupal::service('plugin.manager.entity_reference_selection');
    if ($referenceable = $manager-&gt;getSelectionHandler($field_definition)-&gt;getReferenceableEntities()) {
      $random = new Random();
      $group = array_rand($referenceable);
      $values['target_id'] = array_rand($referenceable[$group]);
      $values['title'] = $random-&gt;sentences(2);
      return $values;
    }
  }

}