Skip to content

prefer_simpler_patterns_null_check

v0.4.0 Warning Fix Control Flow

This rule flags an if-case pattern that spells a null check as != null && final x where Dart has a shorter form that means the same thing.

Two shapes are reported:

  • != null && final x — the postfix ? in final x? already binds only when the value is non-null.
  • != null && final String x — the type annotation is non-nullable, so the != null was already implied.

See also: Patterns

Reading a nullable field through an if-case, then testing it for null on the way in:

class Session {
const Session(this.token);
final String? token;
}
void authorize(Session session) {
if (session.token case != null && final token) {
print('Bearer $token');
}
}

The typed form has the same redundancy — String already excludes null:

class Session {
const Session(this.token);
final String? token;
}
void authorize(Session session) {
if (session.token case != null && final String token) {
print('Bearer $token');
}
}

The quick fix rewrites both. final token? binds only when the value is non-null:

class Session {
const Session(this.token);
final String? token;
}
void authorize(Session session) {
if (session.token case final token?) {
print('Bearer $token');
}
}

And the typed form drops the check, keeping the annotation:

class Session {
const Session(this.token);
final String? token;
}
void authorize(Session session) {
if (session.token case final String token) {
print('Bearer $token');
}
}

Only != null && <binding> is reported, and only when the right operand binds a variable. These stay as they are:

class Session {
const Session(this.token);
final String? token;
}
void checks(Session session, int value) {
// Nothing is bound, so there is no shorter form.
if (session.token case != null) {
print('signed in');
}
// An `||` is not the same test, and is left alone.
if (session.token case != null || '') {
print('either');
}
// No null check involved.
if (value case > 0 && < 10) {
print('in range');
}
}

This rule is in the recommended preset, so it is on with preset: recommended or preset: opinionated. Add it to preset: core with prefer_simpler_patterns_null_check: true.

To turn it off:

many_lints.yaml
rules:
prefer_simpler_patterns_null_check: false

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