Skip to content

prefer_conditional_expressions

v1.0.0WarningControl Flow

This rule flags an if/else that does nothing but assign or return two values.

Six lines to choose between two strings buries the one thing that varies. A conditional expression puts the choice and both outcomes on one line, and makes it obvious that every path assigns exactly once — which the block form only implies.

Both branches assign the same target:

String describe({required bool isActive}) {
String label;
if (isActive) {
label = 'On';
} else {
label = 'Off';
}
return label;
}

Both branches return:

String greeting({required bool isMorning}) {
if (isMorning) {
return 'Good morning';
} else {
return 'Good evening';
}
}
String describe({required bool isActive}) {
final label = isActive ? 'On' : 'Off';
return label;
}
String greeting({required bool isMorning}) =>
isMorning ? 'Good morning' : 'Good evening';

Only the two shapes where the rewrite is exact are reported. These are all left alone, because collapsing them would change what the code does:

String describe({required bool isActive}) {
String label;
String tone;
// Two statements in a branch.
if (isActive) {
label = 'On';
tone = 'green';
} else {
label = 'Off';
tone = 'grey';
}
// Different targets.
if (isActive) {
label = 'On';
} else {
tone = 'grey';
}
// Different operators — `=` in one branch, `+=` in the other.
if (isActive) {
label = 'On';
} else {
label += 'Off';
}
// No `else`.
if (isActive) {
label = 'On';
}
return '$label$tone';
}

An else if chain is a sequence of tests rather than a two-way choice, and a pattern if (if (x case ...)) binds variables a conditional expression cannot — both are skipped.

This rule is in the pedantic preset. Enable it by name:

many_lints.yaml
rules:
prefer_conditional_expressions: true

To turn it off again:

many_lints.yaml
rules:
prefer_conditional_expressions: false

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