Skip to content

prefer_returning_shorthands

v0.3.0 Warning Fix Shorthand Patterns

This rule flags an arrow function that constructs the very type it declares as its return type. The declared type already names the class, so .new(...) or .named(...) carries the same information in fewer characters. The quick fix drops the prefix.

See also: Dart language — dot shorthands

class Money {
const Money(this.amount);
const Money.zero() : amount = 0;
final int amount;
}
Money parsePrice(String raw) => Money(int.parse(raw)); // LINT
Money emptyCart() => Money.zero(); // LINT
Money priceOr(String? raw, bool free) =>
free ? Money.zero() : Money(int.parse(raw!)); // LINT twice
Money parsePrice(String raw) => .new(int.parse(raw));
Money emptyCart() => .zero();
Money priceOr(String? raw, bool free) =>
free ? .zero() : .new(int.parse(raw!));

Both branches of a conditional are checked independently, so a mixed expression reports only the branches that construct the return type.

Money? accepts a Money, so the shorthand is available there too:

// Don't
Money? tryParse(String raw) => Money(int.parse(raw));
// Do
Money? tryParse(String raw) => .new(int.parse(raw));

The rule reads a method’s declared return type the same way, and treats a factory constructor’s class as its return type:

// Don't
class Money {
const Money(this.amount);
const Money._(this.amount);
factory Money.fromCents(int cents) => Money._(cents ~/ 100); // LINT
final int amount;
Money doubled() => Money(amount * 2); // LINT
}
// Do
class Money {
const Money(this.amount);
const Money._(this.amount);
factory Money.fromCents(int cents) => ._(cents ~/ 100);
final int amount;
Money doubled() => .new(amount * 2);
}

Only arrow bodies. A block body is not reported, even when its single return constructs the declared type:

// Not reported
Money parsePrice(String raw) {
return Money(int.parse(raw));
}

A declared return type is required. With no annotation, or with dynamic or void, there is no context type and the shorthand would not compile — nothing is reported.

Only the outermost expression. Money('1').copy() returns a Money but the expression is a method call on a constructor, so it is left alone.

This rule is in the opinionated preset, so it is on with preset: opinionated, or by name:

many_lints.yaml
rules:
prefer_returning_shorthands: true

To turn it off again:

many_lints.yaml
rules:
prefer_returning_shorthands: false

To keep the rule on but skip certain paths, use per-rule exclude.