๐ŸŽ“ A1Learner
๐Ÿ”
0 of 24 lessons completed

Dart Extension Types

An extension type gives a value of an existing type a new static type with its own members. The existing type underneath is the representation type.

A distance type over int

Meters adds a named constructor, a getter, and an addition operator over an int. The prints show the stored metres, the getter result, and the total built by the operator.

extension type Meters(int value) {
  Meters.fromCentimetres(int cm) : value = cm ~/ 100;
  bool get canWalk => value <= 2000;
  Meters operator +(Meters other) => Meters(value + other.value);
}

void main() {
  var walk = Meters(1500);
  var extra = Meters.fromCentimetres(50000);
  print('${walk.value} metres');
  print('can walk: ${walk.canWalk}');
  var total = walk + extra;
  print('total ${total.value} metres');
}

A plain int is not a Meters

The variable is declared as Meters, but 5 is a plain int. The compiler refuses the assignment and prints this error.

extension type Meters(int value) {}

void main() {
  Meters m = 5;
  print(m.value);
}

Erasure at run time

The runtimeType of a Meters value prints int, the representation type. The representation field is read directly, and plain int addition runs on it.

extension type Meters(int value) {}

void main() {
  var walk = Meters(1200);
  print(walk.runtimeType);
  print(walk.value);
  print(walk.value + 300);
}

Example

extension type Celsius(int degrees) {
  int get fahrenheit => degrees * 9 ~/ 5 + 32;
  bool get isFreezing => degrees <= 0;
}

void main() {
  var warm = Celsius(25);
  print('${warm.degrees} degrees');
  print('${warm.fahrenheit} fahrenheit');
  var cold = Celsius(0);
  print('freezing: ${cold.isFreezing}');
}

Key points

  • An extension type declaration names its representation type in parentheses, as in Meters(int value).
  • Inside the type, the representation value is read through its field, here value.
  • An extension type can add named constructors, getters, and operators of its own.
  • A plain value of the representation type cannot be assigned to an extension type variable, as the error exhibit shows.
  • At run time an extension type value is its representation type, so its runtimeType prints the representation type name.
  • That erasure is why an extension type costs nothing at run time.

In this example, Celsius is an extension type over int. The fahrenheit getter converts with whole number arithmetic, so 25 degrees becomes 77. The isFreezing getter reports true for zero degrees.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท DartPad

Exercise

What does the runtimeType of a Meters value print, where Meters is an extension type over int?