Skip to content
Blog

Dart Enhanced Enums: Constants, Constructors, and Members in One Declaration

Enhanced enums turned Dart's enums from bare constant lists into full-featured classes. Learn how to add fields, constructors, methods, and getters to an enum — and when a sealed class is still the better tool.

Published on • October 21, 2026

AI Assistant

For years, a Dart enum was a flat list of constants and nothing else. If you wanted a value to carry data, or a set of related constants to share behavior, you reached for a sealed class. Enhanced enums collapsed much of that gap: an enum can now declare fields, constructors, methods, getters, and even implement interfaces — while remaining, at its core, an enum that exhaustively switches.

Source: Enhanced enums and the Dart language evolution, The Dart Team.

From constants to carriers

The classic limitation looked like this: you wanted each case to know something about itself — a severity level with an associated number, a status with a display label — and an enum could not hold that. Enhanced enums add exactly that capability:

enum Severity {
  low(1),
  medium(2),
  high(3),
  critical(4);

  const Severity(this.level);
  final int level;

  bool get isElevated => level >= 3;
}

Each constant now passes a value to a private constructor, carries it in a field, and exposes behavior through getters and methods. Severity.high.level is 3. Crucially, the declaration is still an enum — values works, and a switch over it remains exhaustive.

The mechanics worth knowing

A few rules govern how these declarations fit together:

  • The constants must come first. The value list is the enum’s identity; members follow it, separated by a semicolon.
  • Constructors are implicitly const. Enum constructors are const and private by convention, so the constants can be compile-time values.
  • You can implement, but not extend. An enum implicitly implements Enum, and you can add implements for interfaces. You cannot extend a class, because every enum already has Enum as its supertype.
  • Methods can be abstract — useful when different constants should behave differently, letting each case override a member.

That last point is what makes enums a genuine alternative to small sealed hierarchies: instead of a switch scattered across your code, behavior can live on the constant that owns it.

Enums or sealed classes?

Both cover “a closed set of variants with behavior,” so the choice is not always obvious. Enums fit when each variant is a distinct, data-carrying value — states, severities, types — where identity matters more than rich per-variant logic. Sealed classes fit when variants are heterogeneous shapes with different fields, deep behavior, or where you want the exhaustiveness of pattern matching over structural data.

The two compose well, though. With Dart’s pattern matching, an enhanced enum with a method per constant handles the simple cases inline, and a sealed class handles the complex ones — and both switch exhaustively, which is the property you actually care about.

Where they pay off

The everyday wins are modest but constant: configuration constants that carry their own metadata, status codes that know their HTTP meaning, UI enums that know their label and icon. Each of these stops being a parallel switch somewhere else in the codebase and becomes a field on the value that already knows the answer — which is exactly the kind of small consolidation that keeps a growing codebase legible.

Key takeaways

Enhanced enums let a Dart enum carry fields, use constructors, and define methods and getters, while staying an exhaustive-switchable enum. The value list must come first, constructors are implicitly const, and enums can implement interfaces but not extend classes. Reach for an enum when variants are data-carrying values with light per-variant behavior; keep a sealed class for heterogeneous variants with rich structure — and use pattern matching to switch over either.

Further reading