I have this code:

class GroceryItemRepository extends ARepository<GroceryItemDomainEntity, int> {
  GroceryItemRepository(IHttpDataSource httpDataSource)
      : super(httpDataSource, 'GroceryItems');
}

Which causes this compile-time error:

'GroceryItemDomainEntity' doesn't extend 'ADomainEntity<GroceryItemDomainEntity, int>'.
Try using a type that is or is a subclass of 'ADomainEntity<GroceryItemDomainEntity, int>'

I can't tell why GroceryItemDomainEntity doesn't extend ADomainEntity<GroceryItemDomainEntity, int>.

Here is the class hierarchy:

abstract class GroceryItemDomainEntity extends AVeganItemDomainEntity
    implements _$GroceryItemDomainEntity {

abstract class AVeganItemDomainEntity
    extends ADomainEntity<AVeganItemDomainEntity, int> {

abstract class ADomainEntity<EntityType, IdType> extends AEntity<EntityType>
    implements IDomainEntity<EntityType, IdType> {

abstract class AEntity<EntityType> implements IEntity<EntityType> {

It works when I declare GroceryItemDomainEntity as:

abstract class GroceryItemDomainEntity extends ADomainEntity<GroceryItemDomainEntity, int>

But I need GroceryItemDomainEntity to contain the members of AVeganItemDomainEntity. Why does GroceryItemDomain entity not extend ADomainEntity<GroceryItemDomainEntity, int>?

EDIT - sorry I missed this class:

import 'package:vepo/src/common/constants/environment_constants.dart';
import 'package:vepo/src/data/data_sources/remote/i_remote_data_source.dart';
import 'package:vepo/src/domain/common/domain_entity/a_domain_entity.dart';

import 'i_repository.dart';

abstract class ARepository<EntityType extends ADomainEntity<EntityType, IdType>,
    IdType> implements IRepository<EntityType> {
  ARepository(this.httpDataSource, this.$baseUri);

  final IHttpDataSource httpDataSource;
  final String $baseUri;

  @override
  Future<EntityType> $fetch() {
    throw UnimplementedError();
  }

  @override
  Future<EntityType> $save({EntityType entity}) {
    var uri = $baseUri;
    if (entity.id != null) {
      uri = uri + '${entity.id}';
    }
    final Uri theUri = Uri(path: '${EnvironmentConstants.of().apiUrl}/$uri');
    return httpDataSource.post<EntityType>(theUri, body: entity);
  }
}


Solution 1: Navaneeth P

AVeganItemDomainEntity extends ADomainEntity<AVeganItemDomainEntity, int>
GroceryItemDomainEntity extends AVeganItemDomainEntity

So GroceryItemDomainEntity extends ADomainEntity<AVeganItemDomainEntity, int>.

In GroceryItemRepository extends ARepository<GroceryItemDomainEntity, int>, the EntityType is GroceryItemDomainEntity.

However

ARepository<EntityType extends ADomainEntity<EntityType, IdType>, IdType>

Since EntityType is GroceryItemDomainEntity, ARepository expects GroceryItemDomainEntity to extend ADomainEntity<GroceryItemDomainEntity, int> but it instead extends ADomainEntity<AVeganItemDomainEntity, int>.

AVeganItemDomainEntity is a super class of GroceryItemDomainEntity. So, AVeganItemDomainEntity cannot be used where GroceryItemDomainEntity is expected. But the other way is possible.

This requires changing what EntityType extends in ARepository. A possible solution I can think of is to use a concrete base type like AEntity or ADomainEntity.

ARepository<EntityType extends ADomainEntity<AEntity, IdType>, IdType>
ARepository<EntityType extends ADomainEntity<ADomainEntity, IdType>, IdType>

or just

ARepository<EntityType extends ADomainEntity, IdType>