Waarom heeft de && operator produceren het type van de tweede operand

stemmen
24

De typoscript specificatie staten in §4.15.6 over de &&exploitant:

De && operator maakt de operanden van elk type zijn en produceert een resultaat van hetzelfde type als de tweede operand .

In Javascript, de &&operator geeft de eerste operand als het falsy, anders geeft de tweede operand ( zie ECMA-262 §11.11 ).

Dat betekent dat als de linker operand falsy, &&een waarde die overeenkomt met het type van de linker operand terug. Bijvoorbeeld,

typeof ( false && {}      ) === boolean // true
typeof ( ''    && 1       ) === string  // true
typeof ( null  && hello ) === object  // true
typeof ( NaN   && true    ) === number  // true

Typescript, volgens de hierboven aangehaalde regel zou verkeerd voorspellen van de types van de bovenstaande uitdrukkingen te zijn Object, Number, Stringen Boolean, respectievelijk.

Mis ik iets? Is er een goede reden om het type van een &&expressie overeenkomen met het type van de tweede operand? Moet niet het type resultaat gedragen zich als de ||operator, en de terugkeer van de beste voorkomende vorm van de twee operanden, en Anyals er geen beste voorkomende type?

De vraag is gesteld op 02/10/2012 om 16:50
bron van user
In andere talen...                            


1 antwoorden

stemmen
20

Lang verhaal kort, er is geen oplossing hier dat iedereen wil.

Beschouw dit gemeenschappelijke idioom:

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

Het zou vrij zwak zijn om te geven en besluiten dat 'adres' is 'elke', want er is geen beste voorkomende vorm tussen Klant en Adres.

In de meeste gevallen waarin het && operator wordt gebruikt, ofwel de reeds passen of && wordt gebruikt in een waarde coalescerende manier als hierboven. In beide gevallen is het retourneren van de aard van de rechter operand geeft de gebruiker het verwachte type.

Terwijl het type veiligheid is technisch breken op dit punt, het is niet te doen op een manier die waarschijnlijk resulteren in een fout. Of je gaat naar de resulterende waarde voor truthiness testen (in welk geval het type is min of meer irrelevant), of je gaat naar de vermoedelijke rechter operand te gebruiken voor een bewerking (het bovenstaande voorbeeld het doen van beide).

Als we kijken naar de voorbeelden die u opgenomen en doen alsof de linker operand is van onbepaalde truthy of falsy en dan proberen om gezond code die zou werken op de return waarde te schrijven, wordt het een stuk duidelijker - er is gewoon niet veel wat je kunt doen met een 'valse && {}', die nog niet is in te gaan op een' geen argument positie of truthiness test.


bijvoegsel

Omdat sommige mensen waren niet overtuigd door het bovenstaande, hier is een andere verklaring.

Laten we doen alsof voor een moment dat het type typescript systeem drie nieuwe types toegevoegd: Truthy<T>, Falsy<T>en Maybe<T>vertegenwoordigen mogelijk truthy / falsy waarden van het type T. De regels voor deze soorten zijn als volgt:

  1. Truthy<T> gedraagt ​​zich precies zoals T
  2. U kunt geen toegang tot alle eigenschappen van Falsy<T>
  3. Een expressie van het type Maybe<T>, indien gebruikt als voorwaarde per ifblok, wordt een Truthy<T>in het lichaam van hetzelfde ifblok en Falsy<T>in het elseblok

Dit zou laten je dingen doen als dit:

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

Best goed tot nu toe. Nu kunnen we erachter te komen wat de soort regels zijn voor het && operator.

  • Truthy<T> && x zou een fout zijn - als de linkerzijde is bekend truthy te zijn, moet je gewoon hebben geschreven x
  • Falsy<T> && xmoet een fout - als de linkerzijde is bekend falsy te zijn, xis dode code
  • Maybe<T> && x moeten produceren ... wat?

We kennen het resultaat van Maybe<T> && xofwel een falsy waarde van het type zijn T, of x. Het kan geen Truthy<T>(tenzij T== het soort xwaarbij deze hele discussie moot). Laten we noemen dit nieuwe type Falsy<T> XOR Maybe<U>.

Wat moet de regels van Falsy<T> XOR Maybe<U>zijn?

  • Het is duidelijk dat je niet de eigenschappen van het gebruik Top. Als de waarde is van het type T, het is falsy, en niet veilig voor gebruik.
  • Je moet in staat zijn om het te gebruiken als een Maybe<U>, aangezien Falsy<T>en Falsy<U>hebben dezelfde gedragingen
  • Je moet niet in staat zijn om de eigenschappen van de te gebruiken U, omdat de waarde nog steeds falsy zou kunnen zijn.
  • Als je het gebruikt in een iftest, dan moet het uitgegroeid tot een Truthy<U>in het blok van die ifverklaring

Met andere woorden, Falsy<T> XOR Maybe<U> is Maybe<U> . Hieruit volgt allemaal dezelfde regels. U hoeft niet om het type systeem compliceren hier helemaal door het toevoegen van deze vreemde XORsoort, omdat een type dat alle specificaties die u nodig hebt past al bestaat.

Dit is een beetje als het geven van iemand een doos en zeggen: "Dit is of een lege doos van afval, of een volle doos van recyclebare". U kunt veilig legen van de inhoud van de doos in de prullenbak.

antwoordde op 02/10/2012 om 17:55
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more