Un caso curioso de los ternarios
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
El formato de los ternarios siempre ha sido un desafío, y finalmente lo abordamos en la versión 3.1.0 con la introducción de un estilo de formato novedoso.
Sigue leyendo para conocer nuestro recorrido y la motivación detrás de este cambio, junto con los comentarios iniciales de los desarrolladores y una descripción general del estilo de "ternarios curiosos".
¡Prueba la opción --experimental-ternaries y cuéntanos qué opinas!
Para un resumen rápido (tl;dr), consulta la publicación de lanzamiento.
Introducción
Dar formato a ternarios anidados de manera adecuada en una amplia variedad de escenarios es un desafío sorprendentemente complejo.
Los desarrolladores los han considerado tan confusos de leer que terminan refactorizando su código a una serie poco elegante de declaraciones if-else, a menudo con una declaración let, una IIFE o una función separada por completo.
Según los beta testers, el nuevo estilo de formato que hemos desarrollado puede requerir cierto tiempo de adaptación, pero finalmente permite usar los ternarios prácticamente como una forma concisa de expresiones if-else en bases de código modernas.
Antecedentes históricos
El enfoque original e ingenuo de Prettier - simplemente agregar sangría a cada nivel de un ternario anidado - funcionaba bien en casos simples, pero obviamente no escala a cadenas largas de ternarios anidados y tenía otros problemas.
Así que en 2018, lo reemplazamos con ternarios planos, lo cual parecía una buena idea en ese momento, pero no fue bien recibido - la incidencia que pedía revertirlo superó ampliamente los 500 votos.
Aunque finalmente revertimos a los ternarios con sangría, queríamos encontrar una mejor solución.
Durante los últimos años, exploramos y experimentamos con muchas soluciones posibles que fueran tan legibles como los ternarios con sangría en casos comunes, pero que también escalaran bien en una mayor variedad de situaciones.
Criterios desafiantes
Idealmente, encontraríamos un esquema que cumpliera con nuestros criterios:
-
En todos los casos, debería ser fácil seguir "cuál es el
if", "cuál es elthen" y "cuál es elelse" - y a qué se corresponden. -
El código debería fluir naturalmente desde un solo ternario, a una cadena de 2, a una cadena larga de casos simples, hasta algo más complejo con algunas condiciones anidadas. (La mayoría de alternativas que exploramos fallaron esta prueba).
-
La sintaxis en JSX, expresiones condicionales de TypeScript (que no pueden expresarse con
if) y JS normal deberían verse y sentirse iguales. -
Debería escalar a cadenas de ternarios anidados de longitud arbitraria (imagina un tipo condicional de TypeScript con docenas de casos alternativos).
Los ternarios con sangría claramente fallaron en (4), discutiblemente en (1), e incluso en (3) - casi siempre hemos impreso ternarios en JSX en un formato plano pero legible que desafortunadamente se sentía antinatural fuera de JSX.
Muchos en la comunidad se entusiasmaron con un "estilo de casos", inspirándose en la sintaxis match de lenguajes como Rust u OCaml, pero no cumplía con el criterio (2) y otros objetivos.
Una solución sorprendente
La buena noticia es que encontramos un algoritmo de formato que cumple nuestros criterios. La mala noticia es que es novedoso y, por tanto, desconocido para la mayoría de desarrolladores.
En las pruebas beta, observamos que los desarrolladores eran bastante escépticos al verlo por primera vez:

Pero tras usarlo un tiempo, ya no querían volver atrás:

Otro desarrollador comentó:
En mi primera hora con la regla activada, se sentía un poco raro. Pero para la segunda hora, ya lo había usado varias veces para resolver problemas que de otro modo habrían requerido refactorizaciones feas con sentencias
if. No pienso volver atrás.
Solía odiar los ternarios anidados, pero también detesto transformar una línea de código limpia en declaraciones
if-else. La nueva regla añade una expresión lineal comprensible deif-else,if-elseal lenguaje y es mucho mejor que múltiples ternarios como ramas anidadas.
Así que consideramos que teníamos una fórmula ganadora, aunque sabíamos que podría ser impactante para la comunidad.
Por ello, decidimos ocultar este nuevo formato tras una opción temporal --experimental-ternaries durante unos meses, y mientras tanto lanzar lo que la comunidad ha estado pidiendo: ternarios con sangría.
Resumen del estilo
Entonces, ¿cómo es exactamente este nuevo estilo?
Un ejemplo rápido y artificial para mostrar la lógica de los ternarios "curiosos":
const animalName =
pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
-
Cada línea que termina con signo de interrogación es un "if".
- Si ves
foo ?es como plantear una pregunta sobre foo – "si foo? entonces, …".
- Si ves
-
Cada línea que comienza con
:es un "else".- Si ves
: foosignifica "sino, foo". - Si ves
: foo ?significa "sino, si foo?".
- Si ves
-
Cada línea sin
:ni?es un "then".- Si solo ves
foo, significa "entonces foo".
- Si solo ves
Y aquí el código reescrito para demostrar ternarios de "estilo caso":
const animalName =
pet.isScary() ? 'wolf'
: pet.canBark() ? 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
Puede verse como una forma concisa de obtener algo similar a la sintaxis match en JavaScript, usando solo el humilde operador ternario (aunque le faltan varias características).
Nuestro nuevo formato es una mezcla fluida de ternarios "curiosos" (donde el signo de interrogación siempre está al final de la línea) y ternarios de "estilo caso", donde el signo de interrogación está en medio de la línea.
Por ejemplo:
const animalName =
pet.canSqueak() ? 'mouse'
: pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: pet.canSqueak() ? 'mouse'
: 'probably a bunny';
¡Déjanos tu feedback!
Esperamos que te guste la nueva opción predeterminada más legible, y realmente esperamos que pruebes la nueva opción --experimental-ternaries durante algunas semanas y nos cuentes qué te parece.
Por favor, danos tu opinión a través de Google Forms: https://forms.gle/vwEuboCobTVhEkt66
