Krótko mówiąc, nie ma tu rozwiązanie, które zadowala wszystkich.
Rozważmy ten wspólny 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
}
Byłoby dość kulawy zrezygnować i zdecydować, że „adres” jest „każdy”, ponieważ nie ma najlepszy spotykany typ pomiędzy Klientem i adres.
W większości przypadków, w których operator && jest stosować albo typy już same, lub && jest używany w taki sposób wartości koalescencji jak wyżej. W każdym razie, wracając typ prawego argumentu daje użytkownikowi oczekiwanego typu.
Chociaż bezpieczeństwo typ jest technicznie uszkodzi się w tym momencie, to nie robi tego w sposób, który jest prawdopodobne, aby spowodować wystąpienie błędu. Albo masz zamiar przetestować wypadkową wartość dla truthiness (w tym przypadku typ jest mniej lub bardziej nieistotne), lub masz zamiar użyć wstępną prawy operand jakiegoś działania (przykład powyżej robi obie).
Jeśli spojrzymy na przykładach ty giełdowych i udawać lewy argument jest indeterminately truthy lub falsy a następnie spróbuj napisać sane kod, który działałby na zwracanej wartości, staje się dużo jaśniej - nie tylko wiele można zrobić z „false && {}”, który nie jest już wchodząc w dowolnej pozycji«»argumentu lub testu truthiness.
Uzupełnienie
Ponieważ niektórzy ludzie nie byli przekonani o powyższym, oto inny wyjaśnienie.
Załóżmy, że na chwilę, że system typ maszynopis plus trzy nowe typy: Truthy<T>, Falsy<T>, i Maybe<T>, co stanowi ewentualne truthy / wartości falsy typu T. Zasady te typy są następujące:
Truthy<T> zachowuje się dokładnie tak, jak T
- Nie można uzyskać dostępu do żadnych właściwości
Falsy<T>
- Wyrażenie rodzaju
Maybe<T>, gdy stosuje się jako stan, w ifbloku staje się Truthy<T>w organizmie tego samego ifbloku, i A Falsy<T>w elsebloku
To pozwoli Ci robić takie rzeczy:
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!
}
Całkiem dobre do tej pory. Teraz możemy dowiedzieć się, jakie zasady typu są dla operatora &&.
Truthy<T> && x powinien być błąd - jeśli po lewej stronie jest znany truthy, należy właśnie napisane x
Falsy<T> && xpowinien być błąd - jeśli po lewej stronie jest znany falsy, xjest martwy kod
Maybe<T> && x powinny produkować ... co?
Wiemy, że wynikiem Maybe<T> && xbędzie albo falsy wartość typu T, lub x. To nie może produkować Truthy<T>(chyba T== typ xw takim przypadku cała ta dyskusja jest dyskusyjna). Nazwijmy ten nowy typ Falsy<T> XOR Maybe<U>.
Jakie powinny być zasady Falsy<T> XOR Maybe<U>być?
- Oczywiście, nie można użyć właściwości
Tna nim. Jeżeli wartość jest typu T, to falsy, i nie jest bezpieczne do użycia.
- Powinieneś być w stanie wykorzystać go jako
Maybe<U>, skoro Falsy<T>i Falsy<U>mają te same zachowania
- Nie powinno być w stanie wykorzystać właściwości
U, ponieważ wartość nadal może być falsy.
- Jeśli używamy go w
ifteście, to powinno stać się Truthy<U>w bloku z tym ifstwierdzeniem
Innymi słowy, Falsy<T> XOR Maybe<U> jest Maybe<U> . Wynika z tego, wszystkie te same zasady. Nie trzeba skomplikować system typu w ogóle tutaj dodając ten dziwny XORtyp, ponieważ typ, który pasuje do wszystkich specyfikacji musisz już istnieje.
To jest trochę jak dając komuś pole i mówiąc: „To jest albo pusta skrzynka śmieci lub pełne pudełko z surowców wtórnych”. Można bezpiecznie opróżnić zawartość pudełka do kosza.