Pe scurt, nu există nici o soluție aici care place tuturor.
Luați în considerare acest idiom comun:
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
}
Ar fi destul de lame să renunțe și să decidă că „adresa“ este „orice“, pentru că nu există nici cel mai bun tip comun între Client și adresă.
În majoritatea cazurilor în care se utilizează operatorul &&, fie tipurile deja se potrivesc, sau && este utilizat într - o manieră valoare de coalescență ca mai sus. În ambele cazuri, revenind tipul operandului din dreapta oferă utilizatorului tipul de așteptat.
În timp ce siguranța de tip este de rupere jos punct de vedere tehnic, în acest moment, nu face acest lucru într-un mod care ar putea avea ca rezultat o eroare. Ori vei testa valoarea rezultată pentru truthiness (caz în care tipul este mai mult sau mai puțin irelevante), sau ai de gând să utilizați drept prezumtiv pentru operandul o operație (exemplul de mai sus face ambele).
Dacă ne uităm la exemple pe care le enumerate și pretinde că operandul stâng este neprecizat truthy sau falsy și apoi încercați să scrie cod sănătos , care să funcționeze pe valoarea returnată, devine mult mai clar - nu doar de mult vă puteți face cu „fals && {}“ , care nu este deja merge într - o«orice»poziție argument sau testul truthiness.
addenda
Din moment ce unii oameni nu au fost convinși de cele de mai sus, aici este o altă explicație.
Să presupunem pentru un moment că sistemul de tip typescript a adăugat trei noi tipuri: Truthy<T>, Falsy<T>și Maybe<T>, reprezentând valorile posibile truthy / falsy de tip T. Regulile pentru aceste tipuri sunt după cum urmează:
Truthy<T> se comportă exact ca T
- Nu puteți accesa orice proprietăți ale
Falsy<T>
- O expresie de tip
Maybe<T>, atunci când este utilizat ca starea într - un ifbloc, devine Truthy<T>în corpul același ifbloc și un Falsy<T>în elsebloc
Acest lucru ar lăsa să faci lucruri de genul asta:
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!
}
Destul de bine până acum. Acum ne putem da seama ce regulile de tip sunt pentru operatorul &&.
Truthy<T> && x ar trebui să fie o eroare - în cazul în care partea stângă este cunoscută a fi truthy, ar fi trebuit să doar în scris x
Falsy<T> && xar trebui să fie o eroare - în cazul în care partea stângă este cunoscută a fi falsy, xeste imposibil de găsit codul
Maybe<T> && x ar trebui să producă ... ce?
Știm rezultatul Maybe<T> && xva fi o valoare falsy de tip Tsau x. Ea nu poate produce Truthy<T>( cu excepția cazului în T== tipul de xcaz în care toată această discuție este controversată). Să numim acest nou tip Falsy<T> XOR Maybe<U>.
Ce ar trebui regulile să Falsy<T> XOR Maybe<U>fie?
- În mod evident, nu puteți utiliza proprietățile
Tpe ea. Dacă valoarea este de tip T, este falsy, și nu în condiții de siguranță pentru utilizare.
- Tu ar trebui să poată să - l folosească ca
Maybe<U>, din moment Falsy<T>și Falsy<U>au aceleași comportamente
- Nu ar trebui să poată utiliza proprietățile
U, deoarece valoarea ar putea fi încă falsy.
- Dacă îl utilizați într - un
iftest de , atunci ar trebui să devină Truthy<U>în blocul acestei ifdeclarații
Cu alte cuvinte, Falsy<T> XOR Maybe<U> este Maybe<U> . Prin urmare , toate aceleași reguli. Nu aveți nevoie pentru a complica sistemul de tip la toate aici prin adăugarea acestui ciudat XORtip, pentru că un tip care se potrivește toate specificațiile de care aveți nevoie există deja.
Acesta este un pic ca da cineva o cutie și spunând „Acesta este fie o cutie goală de gunoi, sau o cutie plină de materiale reciclabile“. Puteți goli în condiții de siguranță a conținutului cutiei în coșul de reciclare.