Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 14

Generics: Writing Type-Safe Reusable Code

A **generic** is a way to write one piece of code that works with many types, while still keeping Dart's type checks. Instead of writing a separate "box for strings" and "box for numbers," you write one "box of T" — where T is a **type variable**, a placeholder filled in later.
Level: GeneralLength: Mid1 min read

Read at another depth

Generics: Writing Type-Safe Reusable Code

A generic is a way to write one piece of code that works with many types, while still keeping Dart's type checks. Instead of writing a separate "box for strings" and "box for numbers," you write one "box of T" — where T is a type variable, a placeholder filled in later.

Why Generics Matter

Imagine storing items in a plain list without type information. You could put anything in it — and then you'd have to remember what you put there. If you forget, the program can fail when you pull items back out.

Generics solve this: Dart knows what type each collection holds, and it checks that you use it correctly. You have already used generics! Dart lists are actually List<String>, List<int>, and so on.

Code example in dart
void main() {
  // A list that can only hold strings.
  final names = <String>[];
  names.add('Ada');
  // names.add(42); // Error! 42 is not a String.

  final numbers = <int>[1, 2, 3];
  print(numbers.length);
}

Writing Your Own Generic Function

Here is a function that returns the first element of any list:

Code example in dart
T firstOf<T>(List<T> items) {
  if (items.isEmpty) {
    throw StateError('List is empty');
  }
  return items.first;
}

void main() {
  print(firstOf<String>(['a', 'b'])); // a
  print(firstOf<int>([10, 20]));      // 10
}

The <T> after the function name says "this function has a type variable called T." You pass the type in the same way you pass values, and Dart usually infers it for you.

A Generic Class

Classes can have type variables too. Here is a simple box that holds one value of any type:

Code example in dart
class Box<T> {
  final T value;
  Box(this.value);
}

void main() {
  final name = Box<String>('Ada');
  final year = Box<int>(1815);
  print(name.value);
  print(year.value);
}
A diagram showing the class Box of T on the left, with arrows pointing to Box of String, Box of int, and Box of bool on the right.
100%
One generic class, many concrete types
Show diagram source
graph LR
    A["Box<T>"] --> B["Box<String>"]
    A --> C["Box<int>"]
    A --> D["Box<bool>"]

Constraining the Type

Sometimes you want to limit T to certain types. The keyword extends sets a boundary:

Code example in dart
class Shape {
  double area() => 0;
}

class Circle extends Shape {
  final double radius;
  Circle(this.radius);
  @override
  double area() => 3.14159 * radius * radius;
}

// T must be a Shape (or a subclass of Shape).
T biggest<T extends Shape>(List<T> shapes) {
  shapes.sort((a, b) => b.area().compareTo(a.area()));
  return shapes.first;
}

void main() {
  final circle = biggest([Circle(1), Circle(3)]);
  print(circle.area()); // about 28.27
}

Because of the constraint, Dart knows every T has an area() method.

Generics let you write code once, use it everywhere, and let the compiler catch mistakes before your program ever runs.

Exercise

What does Box<int> mean, and what happens if you try Box<int>('hi')?

Show answer

Box<int> is the class Box filled in with the type int, so it can only hold integer values. Passing the string 'hi' is a type error and the program will not compile.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Generics: Writing Type-Safe Reusable Code

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that