Lang historie kort, det er ingen løsning her som gleder alle.
Tenk på dette vanlig idiom:
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
}
Det ville være ganske teit å gi opp og bestemmer at 'adresse' er 'noen' fordi det er ingen beste vanligste typen mellom Kunden og adresse.
I de fleste tilfeller hvor det && operatør brukes, enten de typer som allerede er møter, eller && blir brukt i en verdi koalescerende måte som ovenfor. I begge tilfeller, tilbake den type høyre operand gir brukeren forventet type.
Mens den type sikkerhet er teknisk bryte ned på dette punktet, er det ikke å gjøre det på en måte som er sannsynlig å resultere i en feil. Enten du kommer til å teste den resulterende verdi for truthiness (i så fall hvilken type er mer eller mindre irrelevant), eller du kommer til å bruke den antatte høyre operand for noen operasjon (eksemplet ovenfor gjør begge deler).
Hvis vi ser på eksemplene du oppført og late venstre operand er indeterminately truthy eller falsy og prøv deretter å skrive tilregnelig kode som ville operere på returverdien, blir det mye tydeligere - det er bare ikke mye du kan gjøre med 'falsk && {}' som ikke allerede er kommer inn i en 'hvilken som helst' argument stilling eller truthiness test.
Tillegg
Siden noen mennesker ikke ble overbevist av det ovenstående, her er en annen forklaring.
La oss late som for et øyeblikk at Loggfila type system lagt til tre nye typer: Truthy<T>, Falsy<T>, og Maybe<T>, som representerer mulige truthy / falsy verdier av typen T. Reglene for disse typene er som følger:
Truthy<T> oppfører seg akkurat som T
- Du kan ikke få tilgang til alle egenskapene
Falsy<T>
- Et uttrykk av typen
Maybe<T>, når de brukes som den tilstand i en ifblokk, blir en Truthy<T>i kroppen av den samme ifblokk og en Falsy<T>i elseblokken
Dette vil la deg gjøre ting som dette:
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!
}
Ganske bra så langt. Nå kan vi finne ut hva type reglene er for && operatør.
Truthy<T> && x bør være en feil - hvis venstre side er kjent for å være truthy, bør du nettopp har skrevet x
Falsy<T> && xskulle være en feil - dersom den venstre side er kjent for å være falsy, xer ikke nås kode
Maybe<T> && x skal produsere ... hva?
Vi vet resultatet av Maybe<T> && xvil være enten en falsy verdi av typen T, eller x. Det kan ikke produsere Truthy<T>(med mindre T== type xi så fall hele denne diskusjonen er moot). La oss kalle denne nye typen Falsy<T> XOR Maybe<U>.
Hva bør reglene for Falsy<T> XOR Maybe<U>å være?
- Åpenbart, kan du ikke bruke egenskapene
Tpå den. Hvis verdien er av type T, er det falsy, og ikke trygt for bruk.
- Du bør være i stand til å bruke det som en
Maybe<U>, siden Falsy<T>og Falsy<U>har samme atferd
- Du bør ikke være i stand til å bruke egenskapene
U, fordi verdien fortsatt kan være falsy.
- Hvis du bruker den i en
iftest, så det bør bli en Truthy<U>i blokken av at ifuttalelsen
Med andre ord, Falsy<T> XOR Maybe<U> er Maybe<U> . Det følger alle de samme reglene. Du trenger ikke å komplisere type system i det hele tatt ved å føye til denne rare XORtypen, fordi en type som passer alle spesifikasjonene du trenger allerede eksisterer.
Dette er litt som å gi noen en boks og sier "Dette er enten en tom boks av søppel, eller en hel boks med resirkulering". Du kan trygt tømme innholdet i boksen til gjenvinning bin.