Το TypeScript έχει γίνει το βιομηχανικό πρότυπο για μεγάλης κλίμακας ανάπτυξη ιστού. Ενώ οι περισσότεροι προγραμματιστές γνωρίζουν τα βασικά των interfaces και των τύπων, η πραγματική δύναμη βρίσκεται στο προχωρημένο σύστημα τύπων. Εδώ είναι 5 μοτίβα που θα σας ξεχωρίσουν ως έμπειρο μηχανικό.
1. Generic Constraints
Τα Generics είναι ισχυρά, αλλά μερικές φορές χρειάζεται να περιορίσετε τι μπορεί να περαστεί. Το extends είναι ο σύμμαχός σας εδώ.
interface HasId { id: string; } function getById<T extends HasId>(list: T[], id: string): T | undefined { return list.find((item) => item.id === id); }
Διασφαλίζοντας ότι το T επεκτείνει το HasId, εγγυόμαστε ότι η πρόσβαση στο .id μέσα στη συνάρτηση είναι ασφαλής.
2. Conditional Types
Τα Conditional types σας επιτρέπουν να δημιουργήσετε μη ομοιόμορφες αντιστοιχίσεις τύπων. Η σύνταξη μοιάζει με τον τριαδικό τελεστή στη JavaScript.
type IsString<T> = T extends string ? true : false; type A = IsString<string>; // true type B = IsString<number>; // false
Μια πρακτική περίπτωση χρήσης είναι το φιλτράρισμα τύπων από ένα union:
type Diff<T, U> = T extends U ? never : T; type NonNullable<T> = Diff<T, null | undefined>;
3. Mapped Types
Τα Mapped types σας επιτρέπουν να δημιουργήσετε νέους τύπους βασισμένους σε παλιούς μετασχηματίζοντας ιδιότητες.
type ReadOnly<T> = { readonly [P in keyof T]: T[P]; }; interface User { name: string; age: number; } type ReadOnlyUser = ReadOnly<User>;
Μπορείτε ακόμη να προσθέσετε ή να αφαιρέσετε τροποποιητές:
type Mutable<T> = { -readonly [P in keyof T]: T[P]; };
4. Template Literal Types
Εισήχθησαν στο TypeScript 4.1, αυτά σας επιτρέπουν να χειρίζεστε τύπους συμβολοσειρών απευθείας.
type World = 'world'; type Greeting = `hello ${World}`; // "hello world" type Color = 'red' | 'blue'; type Quantity = 'light' | 'dark'; type Palette = `${Quantity}-${Color}`; // "light-red" | "light-blue" | "dark-red" | "dark-blue"
Αυτό είναι απίστευτα χρήσιμο για την τυποποίηση συμβολοσειρών που ακολουθούν ένα συγκεκριμένο μοτίβο, όπως κλάσεις CSS ή ονόματα συμβάντων.
5. Η Λέξη-κλειδί infer
Η λέξη-κλειδί infer μέσα στα conditional types σας επιτρέπει να εξάγετε τύπους από άλλους τύπους.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; function check(): boolean { return true; } type CheckReturn = ReturnType<typeof check>; // boolean
Εδώ, ζητάμε από το TypeScript να "συμπεράνει" τον τύπο επιστροφής R μιας συνάρτησης και να τον επιστρέψει.
Συμπέρασμα
Η εξοικείωση με αυτά τα μοτίβα σας επιτρέπει να γράφετε βιβλιοθήκες και βοηθήματα που είναι ισχυρά και προσφέρουν εξαιρετική εμπειρία προγραμματιστή (DX). Ο στόχος του προχωρημένου TypeScript δεν είναι η πολυπλοκότητα για χάρη της πολυπλοκότητας, αλλά η ασφάλεια και η εκφραστικότητα.