Μεγάλη ιστορία σύντομη, δεν υπάρχει λύση εδώ που ευχαριστεί όλους.
Εξετάστε αυτό το κοινό ιδίωμα:
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
}
Θα ήθελα να είναι αρκετά κουτσός να παραιτηθεί και να αποφασίσει ότι «η διεύθυνση» είναι «κάθε», επειδή δεν υπάρχει καλύτερο κοινός τύπος μεταξύ του Πελάτη και της διεύθυνσης.
Στην πλειοψηφία των περιπτώσεων όπου χρησιμοποιείται ο χειριστής &&, είτε τα είδη που έχουν ήδη ταιριάζουν, ή && χρησιμοποιείται κατά τρόπο αξίας συνενώνονται όπως παραπάνω. Σε κάθε περίπτωση, επιστρέφοντας το είδος του δικαιώματος τελεστή δίνει στο χρήστη την αναμενόμενη τύπου.
Ενώ η ασφάλεια τύπων είναι τεχνικά χωρίς να χαλάσει σε αυτό το σημείο, δεν είναι κάτι τέτοιο με έναν τρόπο που είναι πιθανό να οδηγήσει σε σφάλμα. Είτε πρόκειται να δοκιμαστεί η προκύπτουσα τιμή για truthiness (στην οποία περίπτωση ο τύπος είναι περισσότερο ή λιγότερο άσχετο), ή θα πάμε να χρησιμοποιήσετε την υποθετική δεξιός όρος για κάποια λειτουργία (το παραπάνω παράδειγμα κάνει και τα δύο).
Αν κοιτάξουμε τα παραδείγματα που αναφέρονται και να υποκρινόμαστε το αριστερό τελεστή είναι αορίστου χρόνου truthy ή falsy και στη συνέχεια προσπαθήστε να γράψετε υγιής κώδικα που θα λειτουργούν με βάση την τιμή επιστροφής, γίνεται μια πολύ σαφέστερη - απλά δεν υπάρχουν πολλά που μπορείτε να κάνετε με την «ψευδή && {}»που δεν είναι ήδη πηγαίνει σε μια“οποιαδήποτε”θέση επιχείρημα ή δοκιμής truthiness.
Προσθήκη
Επειδή μερικοί άνθρωποι δεν πείστηκαν από τα παραπάνω, εδώ είναι μια διαφορετική εξήγηση.
Ας προσποιηθούμε για μια στιγμή ότι το σύστημα τύπου γραφομηχανή προσθέσει τρεις νέους τύπους: Truthy<T>, Falsy<T>, και Maybe<T>, που αντιπροσωπεύουν το δυνατόν truthy / falsy τιμές του τύπου T. Οι κανόνες για αυτά τα είδη είναι τα εξής:
Truthy<T> συμπεριφέρεται ακριβώς όπως T
- Δεν μπορείτε να αποκτήσετε πρόσβαση σε οποιεσδήποτε ιδιότητες
Falsy<T>
- Μια έκφραση της τύπου
Maybe<T>, όταν χρησιμοποιείται ως η κατάσταση σε ένα ifμπλοκ, γίνεται ένα Truthy<T>στο σώμα του ίδιου ifμπλοκ και ένα Falsy<T>στο elseμπλοκ
Αυτό θα σας επιτρέψει να κάνετε πράγματα όπως αυτό:
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!
}
Αρκετά καλά μέχρι στιγμής. Τώρα μπορούμε να καταλάβουμε ποιοι είναι οι κανόνες του τύπου είναι για τον χειριστή &&.
Truthy<T> && x θα πρέπει να είναι ένα λάθος - αν η αριστερή πλευρά είναι γνωστό ότι είναι truthy, θα πρέπει να έχετε μόλις γράψει x
Falsy<T> && xθα πρέπει να είναι ένα λάθος - αν η αριστερή πλευρά είναι γνωστό ότι είναι falsy, xείναι απρόσιτος κώδικα
Maybe<T> && x θα πρέπει να παράγει ... τι;
Γνωρίζουμε το αποτέλεσμα Maybe<T> && xθα είναι είτε ένα falsy αξία του τύπου T, ή x. Δεν μπορεί να παράγει Truthy<T>(αν T== ο τύπος του xοπότε όλη αυτή η συζήτηση είναι αμφισβητήσιμο). Ας το ονομάσουμε αυτό το νέο είδος Falsy<T> XOR Maybe<U>.
Τι θα πρέπει οι κανόνες Falsy<T> XOR Maybe<U>να είναι;
- Σαφώς, δεν μπορείτε να χρησιμοποιήσετε τις ιδιότητες του
Tσε αυτό. Εάν η τιμή είναι του τύπου T, είναι falsy, και δεν είναι ασφαλή για χρήση.
- Θα πρέπει να είναι σε θέση να το χρησιμοποιήσετε ως ένα
Maybe<U>, καθώς Falsy<T>και Falsy<U>να έχουν τις ίδιες συμπεριφορές
- Δεν θα πρέπει να είναι σε θέση να χρησιμοποιούν τις ιδιότητες της
U, επειδή η τιμή εξακολουθεί να είναι falsy.
- Αν το χρησιμοποιήσετε σε μια
ifδοκιμασία, τότε θα πρέπει να γίνει Truthy<U>στο μπλοκ της ifδήλωσης
Με άλλα λόγια, Falsy<T> XOR Maybe<U> είναι Maybe<U> . Επομένως, όλοι τους ίδιους κανόνες. Δεν χρειάζεται να περιπλέξει το σύστημα τύπου καθόλου εδώ με αυτόν τον περίεργο XORτύπο, γιατί ένας τύπος που ταιριάζει όλες τις προδιαγραφές που χρειάζεστε υπάρχει ήδη.
Αυτό είναι λίγο σαν να δίνουμε σε κάποιον ένα κουτί και να λέει «Αυτό είναι είτε ένα άδειο κουτί των απορριμμάτων, ή ένα πλήρες κουτί των ανακυκλώσιμων υλικών». Μπορείτε να αδειάσετε με ασφάλεια τα περιεχόμενα του πλαισίου μέσα στο κάδο ανακύκλωσης.