Have multiple types for one argument for a generic class in Dart

Issue

I want to have a custom class where I can pass the type of my generic argument

Is it possible to do this or I have to use the dynamic type ?

Is there a equivalent to this : Team|Site item;

Or I need to use this : dynamic item;

class Site {
  String name;
  int levels;

  Site({
    required this.name,
    required this.levels,
  });
}

class Team {
  String name;
  String description;

  Team({
    required this.name,
    required this.description,
  });
}


class CustomItem {
  // Related line
  Team|Site item;
  
  CustomItem({
    required this.item,
  });
  
  getName() {
    print(item.name);
  }
  
}

void main() {
  final team = Team(name: 'dev', description: 'a team of dev');
  final site = Site(name: 'paris', levels: 6);
  final customTeam = CustomItem(item: team);
  final customSite = CustomItem(item: site);
  customTeam.getName();
  customSite.getName();
}

Solution

As of Flutter 2.10.3, this feature does not exist yet but there are two workarounds.

If you only need this special handling for one class, #1 works fine but is hard to maintain.

#2 is a better solution — easy to extend, reuse and understand.

1. Use dynamic property and convert the item type.

class CustomItem {
  // Related line
  dynamic item;

  CustomItem({
    required this.item,
  });

  String getName() {
    switch (item.runtimeType) {
      case Site:
        return (item as Site).name;
      case Team:
        return (item as Team).name;
      default:
        return ''; // or throw error
    }
  }
}

  1. Use abstract class with same property name.
abstract class ItemWithName {
  String name;
  ItemWithName({required this.name});
}

class Site extends ItemWithName {
  int levels;

  Site({
    required name,
    required this.levels,
  }) : super(name: name);
}

class Team extends ItemWithName {
  String description;

  Team({
    required name,
    required this.description,
  }) : super(name: name);
}

class CustomItem {
  // Related line
  ItemWithName item;

  CustomItem({
    required this.item,
  });

  String getName() {
    return item.name;
  }
}

Answered By – TYJ

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *