oxc-project/oxc · warning · OxcDiagnostic
Prefer ternary expressions over simple `if-else` statements.
Error message
Prefer ternary expressions over simple `if-else` statements.
What it means
This is the oxlint rule `unicorn/prefer-ternary`. It fires on a simple `if`/`else` whose two branches each contain exactly one statement that assigns to the same target with `=` (via `is_same_expression`/`is_same_member_expression` checks), suggesting a conditional (ternary) expression instead. The `always` (default) option enforces it whenever merging is safe; `only-single-line` restricts it to single-line condition and branches.
Source
Thrown at crates/oxc_linter/src/rules/unicorn/prefer_ternary.rs:22
use serde::Deserialize;
use oxc_ast::{
AstKind,
ast::{AssignmentTarget, Expression, IfStatement, MemberExpression, Statement},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
utils::{is_same_expression, is_same_member_expression, static_string_value},
};
fn prefer_ternary_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Prefer ternary expressions over simple `if-else` statements.")
.with_help("Rewrite this `if`/`else` as a ternary expression.")
.with_label(span)
}
#[derive(Debug, Clone, Copy, Default, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum PreferTernaryOption {
/// Always enforce ternary usage when the branches can be safely merged.
#[default]
Always,
/// Only enforce ternary usage when the condition and both branches are single-line.
OnlySingleLine,
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct PreferTernary(PreferTernaryOption);
declare_oxc_lint!(View on GitHub (pinned to e1e7af627c)
Solutions
- Merge into a ternary: `a = cond ? 1 : 2;` (watch operator precedence — parenthesize the ternary inside larger expressions).
- If the branches or condition are long, extract them: `a = cond ? longExprA() : longExprB();` or keep the if/else and set the rule to `only-single-line` in `.oxlintrc.json`.
- If your style guide bans ternaries in statements, disable `unicorn/prefer-ternary` outright.
Example fix
// before
let level;
if (isDev) {
level = 'debug';
} else {
level = 'info';
}
// after
const level = isDev ? 'debug' : 'info'; Defensive patterns
Strategy: validation
Validate before calling
// Express dual assignment as a conditional from the start const level = isDev ? 'debug' : 'info'; // CI: npx oxlint --deny-warn unicorn/prefer-ternary src/
Prevention
- Use ternaries for single-assignment if/else; stop at one level of nesting.
- Set `only-single-line` in config if multi-line ternaries hurt your reviews.
- Parenthesize ternaries embedded in larger expressions to dodge precedence bugs.
When it happens
Trigger: `if (cond) { a = 1; } else { a = 2; }`, or branches assigning the same member (`obj.x = ...` in both arms), where both branch bodies are single assignment expression statements to a syntactically identical target. Non-assignment branches, differing targets, or `else if` chains with mixed shapes are not flagged.
Common situations: Config/flag selection code (`if (dev) { level = 'debug'; } else { level = 'info'; }`); teams that find nested ternaries unreadable often set `only-single-line` or disable the rule, since the merged form can hurt readability when condition or values grow.
Related errors
- Unnecessary use of boolean literals in conditional expressio
- Prefer `{} {}` over `{} {}` to check {}.
- Invalid escape sequence in template literal.
- No spaces inside empty pair of braces allowed
- Use uppercase characters for the value of the escape sequenc
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/690797763d7cd0c2.
Report an issue: GitHub.