Skip to content

avoid_single_field_destructuring

v0.4.0 Warning Fix Pattern Matching

This rule flags a pattern declaration that pulls out exactly one field. final User(:name) = user; is pattern syntax doing the job of final name = user.name;, and the quick fix rewrites it to that.

Destructuring pays for itself from two fields upward. At one, it is a longer way to write a property read.

See also: Dart patterns

class User {
const User({required this.name, required this.email});
final String name;
final String email;
}
void greet(User user) {
final User(:name) = user; // LINT
print('Hello, $name');
}
void mail(User user) {
final User(email: address) = user; // LINT — renaming does not help
print(address);
}
void greet(User user) {
final name = user.name;
print('Hello, $name');
}
void mail(User user) {
final address = user.email;
print(address);
}

A record pattern binding one field is the same shape and is reported the same way:

// Don't
void report(({int length, String path}) file) {
final (:length) = file; // LINT
print(length);
}
// Do
void report(({int length, String path}) file) {
final length = file.length;
print(length);
}

Two or more fields, and the pattern earns its place — nothing is reported:

void summary(User user) {
final User(:name, :email) = user;
print('$name <$email>');
}
void report(({int length, String path}) file) {
final (:length, :path) = file;
print('$path is $length bytes');
}

Only pattern declarations are checked — a final/var binding with a pattern on the left. A single-field pattern in a switch case or an if-case is doing matching work as well as extraction, so it is never reported:

// Not reported — the pattern also decides whether the branch runs
if (payload case Response(:final body)) {
print(body);
}
switch (event) {
case KeyEvent(:final key):
print(key);
}

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

many_lints.yaml
rules:
avoid_single_field_destructuring: true

To turn it off again:

many_lints.yaml
rules:
avoid_single_field_destructuring: false

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