Ένας περιορισμός γενικού τύπου (T extends ...) περιορίζει ποιοι τύποι μπορεί να είναι μια γενική παράμετρος, ώστε να μπορείτε με ασφάλεια να χρησιμοποιήσετε ορισμένες ιδιότητες ή μεθόδους σε αυτό. Χωρίς περιορισμό, ένας γενικός τύπος θα μπορούσε να είναι οτιδήποτε, επομένως δεν μπορείτε να υποθέσετε ότι έχει κανέναν μέλος.
// ❌ without a constraint, you can't access .length — T might be a number
function longestBad<T>(a: T, b: T) {
return a.length > b.length ? a : b; // Error: 'length' does not exist on 'T'
}
// ✅ constrain T to things that HAVE a length
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length > b.length ? a : b;
}
longest("abc", "de"); // ✅ strings have length
longest([1, 2], [3]); // ✅ arrays have length
longest(1, 2); // ❌ numbers have no length
Ο περιορισμός είναι μια υπόσχεση: "T θα έχει πάντα τουλάχιστον αυτή τη μορφή," το οποίο επιτρέπει στον compiler να επιτρέψει .length ενώ παραμένει T ακριβές (ο τύπος επιστροφής είναι ο πραγματικός τύπος πίνακα/string, όχι ο περιορισμός).
Περιορισμός σε κλειδιά (πολύ κοινό)
function pluck<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
K extends keyof T εγγυάται ότι key είναι μια πραγματική ιδιότητα του obj — και T[K] επιστρέφει τον ακριβή του τύπο.
Προεπιλεγμένες παράμετροι τύπου
interface Box<T = string> { value: T; } // T defaults to string if not specified
Γιατί είναι σημαντικό
Οι περιορισμοί είναι η ισορροπία μεταξύ ευελιξίας και ασφάλειας: επιτρέπουν στον γενικό κώδικα να βασίζεται σε μια ελάχιστη μορφή (έχει .length, έχει κλειδί K, επεκτείνει κάποια βάση) ενώ διατηρούν τον συγκεκριμένο τύπο του καλούντα.
Είναι απαραίτητες για λειτουργίες βοηθείας, ασφαλή πρόσβαση σε αντικείμενα και κάθε γενικό τύπο που πρέπει να κάνει κάτι με την παράμετρο του τύπου.
