Code Smell | Chained Ternary Operators

Code Smell | Chained Ternary Operators

February 4, 2024

codequality
refactorit
code-smell

Ternary operators offer a compact syntax for conditional assignments. However, excessive chaining of these operators can lead to code that is difficult to understand, maintain, and debug. This article highlights the pitfalls of overusing ternary operators and provides alternative solutions to improve code clarity and efficiency.

Cause

Developers may opt for chained ternary operators to achieve brevity in their code. This approach involves nesting multiple ternary expressions, which, while seeming efficient, can obscure the logic and make the code less accessible, especially with complex conditions.

Example

Consider the following example, where chained ternary operators are used to determine a result based on multiple conditions:

let result = condition1
    ? value1
    : condition2
      ? value2
      : condition3
        ? value3
        : defaultValue

This code, aiming for conciseness, sacrifices readability and maintainability.

Solution

Two structured approaches, using a switch statement or an object map, can significantly enhance the readability and maintainability of the code. Below are examples of how to refactor the provided example using both methods.

Using a switch statement:

let result: string
 
switch (currentCondition) {
    case condition1:
        result = value1
        break
    case condition2:
        result = value2
        break
    case condition3:
        result = value3
        break
    default:
        result = defaultValue
}

Using an object map:

const resultMapping = {
    condition1: value1,
    condition2: value2,
    condition3: value3,
}
 
// Assuming 'currentCondition' is a variable that holds the current condition's identifier
let result = resultMapping[currentCondition] || defaultValue

These solutions replace the nested ternary operators with more transparent structures, either through the sequential logic of a switch statement or the direct mapping of conditions to values with an object map.

Benefits

Both the switch statement and the object map offer clear advantages over chained ternary operators:

  • Improved Readability: The logic is easier to follow, making the code more approachable for developers of all skill levels.

  • Enhanced Maintainability: Adding or modifying conditions and their corresponding actions is straightforward, without the need to unravel complex ternary chains.

  • Simplified Debugging: Identifying and resolving issues is more efficient when the code structure clearly separates conditions and outcomes.

In summary, while ternary operators are useful for simple conditional assignments, relying on them excessively, especially in a chained manner, can detract from the code's quality. Utilizing either switch statements or object maps for handling multiple conditions offers a more readable, maintainable, and debuggable approach, aligning with best practices in software development.

Bonus track

We can help ESLint to prevent these types of patterns by enabling the following rule in our configuration:

{
    "rules": {
        "no-nested-ternary": "error"
    }
}

Thanks for reading me 😊

Buy Me A Coffee