Hoppa till huvudinnehållet

Ett märkligt fall av ternära uttryck

· 6 min att läsa
Inofficiell Beta-översättning

Denna sida har översatts av PageTurner AI (beta). Inte officiellt godkänd av projektet. Hittade du ett fel? Rapportera problem →

Formatering av ternära uttryck har alltid varit en utmaning, och i v3.1.0 adresserar vi äntligen detta genom att introducera en ny formateringsstil.

Läs vidare om vår resa och motivationen bakom denna förändring, tillsammans med tidig utvecklarfeedback och en översikt över "curious ternaries"-stilen.

Testa gärna --experimental-ternaries-flaggan och berätta vad du tycker!

För en snabb sammanfattning, se releases-inlägget.

Introduktion

Att formatera nästlade ternära uttryck snyggt i en mängd olika scenarion är en överraskande knepig utmaning.

Utvecklare har länge tyckt att de är så förvirrande att läsa att de istället skriver om sin kod till en följd av fula if-else-satser, ofta med en let-deklaration, en IIFE eller en helt separat funktion.

Enligt betatestare kan den nya formateringsstilen vi utvecklat ta lite tid att vänja sig vid, men gör slutligen att ternära uttryck praktiskt kan användas som en koncis form av if-else-uttryck i moderna kodbaser.

Historisk bakgrund

Prettiers ursprungliga, naiva tillvägagångssätt – att bara lägga till indrag på varje nivå i ett nästat ternärt uttryck – fungerade bra i enkla fall, men skalar uppenbarligen inte till långa kedjor av nästade ternära uttryck och hade andra problem.

Så 2018 ersatte vi det med platta ternära uttryck, vilket verkade som en bra idé då, men mottogs inte väl – ärendet som begärde återgång fick över 500 upvotes.

Även om vi slutligen återgick till indragna ternära uttryck, ville vi hitta ett bättre sätt.

Under de senaste åren har vi utforskat och experimenterat med många, många möjliga lösningar som skulle vara lika läsbara som indragna ternära uttryck i vanliga fall, men också skala väl för att fungera i fler situationer.

Utmanande kriterier

Idealt sett skulle vi hitta ett system som uppfyller våra kriterier:

  1. I alla fall ska det vara enkelt att följa "vad är if", "vad är then" och "vad är else" – och vad de motsvarar.

  2. Koden ska flyta naturligt från ett enkelt ternärt uttryck till en kedja av 2, till en lång kedja av enkla fall, till något mer komplext med några nästade villkor. (De flesta alternativ vi utforskade misslyckades här).

  3. Syntaxen i JSX, TypeScripts villkorsuttryck (som inte kan uttryckas med if) och vanlig JS ska alla se och kännas likadana ut.

  4. Den ska skala till nästlade ternära kedjor av godtycklig längd (tänk dig en TypeScript-conditional-type med dussintals alternativa fall).

Indragna ternära uttryck misslyckades tydligt med (4), eventuellt (1), och till och med (3) – vi har nästan alltid formaterat JSX-ternära uttryck i ett platt men läsbart format som tyvärr kändes onaturligt utanför JSX.

Många i communityt var entusiastiska över en "case-stil", inspirerad av match-syntax från språk som Rust eller OCaml, men den uppfyllde inte (2) och andra mål.

En överraskande lösning

Den goda nyheten är att vi hittat en formateringsalgoritm som uppfyller våra kriterier. Den dåliga är att den är nyskapande och därmed okänd för de flesta utvecklare.

I betatesting av denna funktion upptäckte vi att utvecklare först var ganska skeptiska:

"Jag är inte övertygad om att den nya versionen är enklare att läsa här."

Men efter att ha använt den ett tag ville de inte gå tillbaka:

"Jag gillar ternaries! Jag tycker det är vettigt att formatera dem så här. Jag vande mig också ganska snabbt.\nJag håller med, det tar väldigt kort tid att vänja sig."

En annan utvecklare sade så här:

Min första timme med regeln aktiverad kändes lite konstig. Men vid timme två hade jag använt den flera gånger för att lösa problem som annars skulle krävt fula omskrivningar till if-satser. Jag tänker inte gå tillbaka.

Jag brukade hata nästlade ternaries, men jag avskyr också att bryta upp en fin kodrad till if-else-satser. Den nya regeln lägger till ett begripligt, linjärt if-else, if-else-uttryck till språket och är mycket trevligare än flera ternaries som grenar.

Så vi kände att vi hade ett vinnande koncept, men visste att det kunde vara en chock för communityn.

Därför valde vi att lägga denna nya formatering bakom en tillfällig flagga --experimental-ternaries i några månader, och samtidigt leverera det communityt efterfrågat: indenterade ternaries.

Stilöversikt

Så hur ser denna nya stil egentligen ut?

Här ett snabbt, konstruerat exempel som visar tanken bakom "curious" ternaries:

const animalName =
pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
  1. Varje rad som slutar med frågetecken är en "if".

    • Om du ser foo ? är det som att ställa en fråga om foo – "om foo? då, …".
  2. Varje rad som börjar med : är en "else".

    • Om du ser : foo betyder det "annars, foo".
    • Om du ser : foo ? betyder det "annars, om foo?".
  3. Varje rad utan : eller ? är ett "then".

    • Om du bara ser foo betyder det "då foo".

Här samma kod omskriven för att demonstrera "case-style" ternaries:

const animalName =
pet.isScary() ? 'wolf'
: pet.canBark() ? 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';

Du ser att detta är ett elegant sätt att få något som liknar match-syntax i JavaScript, med bara den enkla ternary-operatorn (om än utan flera funktioner).

Vår nya formatering är en smidig blandning av "curious" ternaries (där frågetecknet alltid är i slutet av raden) och "case-style" ternaries, där frågetecknet står mitt på raden.

Exempel:

const animalName =
pet.canSqueak() ? 'mouse'
: pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: pet.canSqueak() ? 'mouse'
: 'probably a bunny';

Ge oss din feedback!

Vi hoppas du gillar den nya standarden som är mer lättläst, och vi hoppas verkligen att du testar det nya alternativet --experimental-ternaries i några veckor och låter oss veta vad du tycker.

Ge oss gärna feedback via Google Forms: https://forms.gle/vwEuboCobTVhEkt66