ZetCode

Dart Dot Shorthand

last modified July 10, 2026

Dot shorthand syntax (.member) lets us write more concise Dart code by omitting the type when the compiler can infer it from context. It provides a clean alternative to writing the full ContextType.member when accessing enum values, static members, or constructors.

Dot shorthands require a language version of at least 3.10.

In essence, dot shorthands allow an expression to start with one of the following:

Dot shorthands with enums

A primary use case for dot shorthands is with enums, especially in assignments and switch statements, where the enum type is obvious from context.

main.dart
enum Status { none, running, stopped, paused }
enum LogLevel { debug, info, warning, error }

String colorCode(LogLevel level) {
  return switch (level) {
    .debug => 'gray',
    .info => 'blue',
    .warning => 'orange',
    .error => 'red',
  };
}

void main() {
  // Dot shorthand in variable assignment
  Status currentStatus = .running;

  print(currentStatus);

  // Dot shorthand in switch expression
  String warnColor = colorCode(.warning);
  print(warnColor);
}

The compiler infers .running to mean Status.running and .warning to mean LogLevel.warning from the context type. In the switch expression, the cases use dot shorthand to match each enum value concisely.

$ dart main.dart
Status.running
orange

Dot shorthands with named constructors

Dot shorthands are useful for invoking named constructors or factory constructors. This syntax also works when providing type arguments to a generic class's constructor.

main.dart
class Point {
  final double x, y;
  const Point(this.x, this.y);
  const Point.origin() : x = 0, y = 0;

  factory Point.fromList(List<double> list) {
    return Point(list[0], list[1]);
  }
}

void main() {
  // Dot shorthand on a named constructor
  Point origin = .origin();

  // Dot shorthand on a factory constructor
  Point p1 = .fromList([1.0, 2.0]);

  print('origin: (${origin.x}, ${origin.y})');
  print('p1: (${p1.x}, ${p1.y})');
}

The compiler infers .origin() as Point.origin() and .fromList() as Point.fromList() from the context type of the variable declaration.

$ dart main.dart
origin: (0, 0)
p1: (1.0, 2.0)

Dot shorthands with unnamed constructors

The .new dot shorthand provides a concise way to call an unnamed constructor of a class. This is useful for assigning fields or variables where the type is already explicitly declared.

Without dot shorthands:

main.dart
class Task {
  final String name;
  final int priority;

  Task(this.name, {this.priority = 0});
}

void main() {
  Task task1 = Task('Write code');
  Task task2 = Task('Review PR', priority: 1);
  List<int> numbers = List<int>.filled(5, 0);

  print('${task1.name}: ${task1.priority}');
  print('${task2.name}: ${task2.priority}');
  print(numbers);
}

With dot shorthands:

main.dart
class Task {
  final String name;
  final int priority;

  Task(this.name, {this.priority = 0});
}

void main() {
  Task task1 = .new('Write code');
  Task task2 = .new('Review PR', priority: 1);
  List<int> numbers = .filled(5, 0);

  print('${task1.name}: ${task1.priority}');
  print('${task2.name}: ${task2.priority}');
  print(numbers);
}

The .new syntax replaces the explicit class name when calling the unnamed constructor. This is particularly effective for cleaning up repetitive field initializers in classes like Flutter's State.

$ dart main.dart
Write code: 0
Review PR: 1
[0, 0, 0, 0, 0]

Dot shorthands with static members

We can use dot shorthand syntax to call static methods or access static fields and getters.

main.dart
void main() {
  // Dot shorthand on static method
  int httpPort = .parse('80');

  // Dot shorthand on static field
  BigInt bigIntZero = .zero;

  // Dot shorthand in a chain
  String lowerH = .fromCharCode(72).toLowerCase();

  print('Port: $httpPort');
  print('BigInt zero: $bigIntZero');
  print('Lower: $lowerH');
}

The compiler infers .parse('80') as int.parse('80'), .zero as BigInt.zero, and .fromCharCode(72) as String.fromCharCode(72) from the context types.

$ dart main.dart
Port: 80
BigInt zero: 0
Lower: h

Dot shorthands in constant expressions

Dot shorthands can be used within a constant context if the member being accessed is a compile-time constant. This is common for enum values and invoking const constructors.

main.dart
enum Status { none, running, stopped, paused }

class Point {
  final double x, y;
  const Point(this.x, this.y);
  const Point.origin() : x = 0.0, y = 0.0;
}

void main() {
  // Dot shorthand for enum value in const context
  const Status defaultStatus = .running;

  // Dot shorthand for const named constructor
  const Point myOrigin = .origin();

  // Dot shorthand in const collection literal
  const List<Point> keyPoints = [.origin(), .new(1.0, 1.0)];

  print(defaultStatus);
  print('(${myOrigin.x}, ${myOrigin.y})');
  print(keyPoints.length);
}

In constant expressions, the dot shorthand resolves to compile-time constants such as enum values or const constructors.

$ dart main.dart
Status.running
(0.0, 0.0)
2

Asymmetric equality checks

The == and != operators have a special rule for dot shorthands. When dot shorthand syntax is used directly on the right-hand side of an equality check, Dart uses the static type of the left-hand side to determine the class or enum for the shorthand.

main.dart
enum Color { red, green, blue }

String describe(Color color) {
  if (color == .green) return 'green like grass';
  if (color != .blue) return 'some other color';
  return 'blue like sky';
}

void main() {
  Color myColor = Color.red;

  print(describe(myColor));
  print(describe(Color.green));
  print(describe(Color.blue));
}

In color == .green, the compiler uses the type of color (Color) to infer .green as Color.green. The dot shorthand must be on the right-hand side of the equality operator.

$ dart main.dart
some other color
green like grass
blue like sky

Rules and limitations

Dot shorthands rely on a clear context type, which leads to several rules and limitations.

Clear context type required

The compiler must be able to infer the type from context. If the context type is ambiguous or missing, the code will not compile.

main.dart
void main() {
  // OK: context type is clear from variable declaration
  int value = .parse('42');

  // ERROR: expression statement cannot start with '.'
  // .parse('42');

  // OK: chaining works when context type is clear
  String lowerH = .fromCharCode(72).toLowerCase();
  print('$value, $lowerH');
}

Expression statements cannot start with dot

To avoid potential parsing ambiguities, an expression statement is not allowed to begin with a . token. Dot shorthands only work in contexts where there is a clear target type, such as variable declarations, return statements, or parameter passing.

Limited union type handling

For nullable types (T?), we can access static members of T, but not of Null. For FutureOr<T>, we can access static members of T, but not of the Future class itself.

Best practices

Source

Dart Dot Shorthands Documentation

This tutorial covered Dart's dot shorthand syntax with practical examples demonstrating its use with enums, constructors, static members, and constant expressions.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.