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:
Truthy<T> gedraagt zich precies zoals T
- U kunt geen toegang tot alle eigenschappen van
Falsy<T>
- 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.