SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions

L'exception JavaScript "cannot use ?? unparenthesized within || and && expressions" se produit lorsque l'opérateur de coalescence des nuls est utilisé avec un OU logique ou avec un ET logique, dans la même expression et sans parenthèses.

Message

SyntaxError: Unexpected token '??' (moteur JavaScript basé sur V8)
SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions (Firefox)
SyntaxError: Unexpected token '??'. Coalescing and logical operators used together in the same expression; parentheses must be used to disambiguate. (Safari)

Type d'erreur

Quel est le problème ?

La précédence des opérateurs ressemble à ceci :

|   >   &&   >   ||   >   =
|   >   ??   >   =

Toutefois, la précédence entre ?? et &&/|| est intentionnellement indéfinie, car le comportement en court-circuit des opérateurs logiques peut rendre l'évaluation d'une expression contre-intuitive. Ainsi, toutes les combinaisons qui suivent entraînent des erreurs de syntaxe, car le langage ne permet pas de savoir quelle opération a la priorité :

js
a ?? b || c
a || b ?? c
a ?? b && c
a && b ?? c

À la place, on utilisera des parenthèses pour rendre explicite l'ordre des opérations voulu :

js
(a ?? b) || c;
a ?? (b && c);

Exemples

Lorsqu'on migre du code historique qui utilise || et && afin de se protéger des valeurs null ou undefined, on peut aboutir à une conversion partielle :

js
function getId(user, fallback) {
  // Avant, on avait : user && user.id || fallback
  return user && user.id ?? fallback; // SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions
}

À la place, on privilégiera l'utilisation de parenthèses autour des opérandes de && :

js
function getId(user, fallback) {
  return (user && user.id) ?? fallback;
}

Mieux encore, on peut utiliser le chaînage optionnel à la place de && :

js
function getId(user, fallback) {
  return user?.id ?? fallback;
}

Voir aussi