A bound on a type parameter restricts which types can fill it. T extends Named means T must implement Named, so the function body can safely call any member declared by Named. One generic function then handles every implementer.

Program

Play the program to call badge<T extends Named> on a City and a Country.

bounded_generics.dart
abstract class Named {
  String get name;
}

class City implements Named {
  @override
  final String name;
  City(this.name);
}

class Country implements Named {
  @override
  final String name;
  Country(this.name);
}

String badge<T extends Named>(T item) => item.name.toUpperCase();

void main() {
  var paris = City('Paris');
  var france = Country('France');
  var labels = '${badge(paris)} / ${badge(france)}';
  print(labels);
}
type bound `T extends Named` says any type filling `T` must implement `Named`.
safe member access Inside `badge`, `item.name` is allowed because every valid `T` has it: no cast, no runtime check.
polymorphic reuse The same `badge` handles `City`, `Country`, and any future `Named` without changes.