tezvyn:

Dart's Enhanced Enums: More Than Just Constants

AI-drafted, machine-checkedSource: dart.devintermediate

An enhanced enum is a class with a fixed set of instances. It lets you add fields, methods, and constructors to your enums, turning them from simple labels into powerful objects with attached data and behavior.

WHY IT EXISTS: Before enhanced enums, associating data with an enum case (like a display string or an API code) required external maps or extension methods. This scattered related logic, making code harder to maintain. Enhanced enums solve this by allowing the data and behavior to live directly inside the enum definition.

THE MENTAL MODEL: An enhanced enum is a sealed class with a fixed, known set of constant instances. It's not just a list of identifiers; it's a full-fledged class where each enumerated value is an object with its own state and methods. For example, an enum Status.success can hold a success message, while Status.error can hold an error code.

HOW IT WORKS: You declare an enum and add instance variables, methods, and a const constructor. You must then declare the enum values at the end of the definition, after a semicolon, providing the constructor arguments for each. All instance fields must be final. Dart automatically makes the enum sealed, meaning you can't subclass it or create new instances outside the declaration.

WHEN TO USE IT: Use enhanced enums when your enum cases have inherent data or behavior that should be tightly coupled. This is ideal for mapping UI states to icons and colors, representing different tiers of a service with specific limits, or associating API status codes with human-readable messages. It keeps related logic neatly bundled together.

WHEN NOT TO USE IT: Stick with simple enums if you just need a list of named constants without any associated data. Using an enhanced enum for a simple Direction { north, south, east, west } is overkill. If the associated data is highly dynamic or fetched from an external source at runtime, a separate class or map is often a better choice.

ONE CANONICAL EXAMPLE: Representing different account tiers with specific properties is a perfect use case. Notice the fields, the const constructor, and the list of values calling that constructor.

enum AccountTier { free(storageLimitMB: 500, canShare: false), premium(storageLimitMB: 5000, canShare: true), enterprise(storageLimitMB: -1, canShare: true); // -1 for unlimited

const AccountTier({ required this.storageLimitMB, required this.canShare, });

final int storageLimitMB; final bool canShare; }

Read the original → dart.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.