Treci la conținutul principal

Tipuri mapate în TypeScript

Un tip mapat construiește un tip nou parcurgând fiecare proprietate a unui tip existent și schimbând-o în același fel.

  • Tipurile mapate = transformă fiecare proprietate a unui tip
  • Cele predefinite uzuale: Partial, Readonly, Pick, Omit, Record

Un mic exemplu de tip mapat

Pornind de la un tip Person, un tip mapat face fiecare proprietate opțională, iar altul face fiecare proprietate readonly.

script.ts
// Small example
type Person = { name: string; age: number };
type PartialPerson = { [P in keyof Person]?: Person[P] };
type ReadonlyPerson = { readonly [P in keyof Person]: Person[P] };

Sintaxa de bază a tipurilor mapate

Sintaxa de bază a unui tip mapat este { [P in K]: T }, unde:

  • P este numele proprietății vizitate în acel moment
  • K este o uniune a numelor de proprietăți care trebuie parcurse (adesea keyof SomeType)
  • T este tipul pe care îl primește fiecare proprietate în tipul nou

Exemplu

PartialPerson adaugă ? la fiecare proprietate a lui Person, așa că este permis un obiect care are doar name. ReadonlyPerson adaugă readonly la fiecare proprietate, așa că o atribuire ulterioară către age ar fi o eroare de compilare.

Prompt
Arată sintaxa de bază a tipurilor mapate { [P in K]: T }, transformând manual o interfață. Declară o interfață Person cu name: string, age: number și email: string. Construiește un tip mapat PartialPerson care face toate proprietățile opționale și creează un obiect partialPerson doar cu name: "John". Apoi construiește un tip mapat ReadonlyPerson care marchează fiecare proprietate readonly, creează un obiect complet readonlyPerson (Alice, 30, [email protected]) și lasă comentată o reatribuire a lui age, explicând că ar fi o eroare de proprietate doar pentru citire. Nu se afișează nimic.
Ieșire: program TypeScript și rezultatul capturat

Tipuri mapate predefinite

Biblioteca standard TypeScript include deja mai multe tipuri mapate utile, așa că nu trebuie să le scrii singur pe cele uzuale:

  • Partial<T>: face toate proprietățile opționale
  • Readonly<T>: face toate proprietățile readonly
  • Pick<T, K>: păstrează doar un set ales de chei
  • Omit<T, K>: elimină un set de chei
  • Record<K, V>: asociază unui set de chei un singur tip de valoare

Exemplu

Fiecare alias de mai jos aplică un tip mapat predefinit lui User. Comentariul de după fiecare alias arată tipul obiect pe care îl produce. Este arătat și Required — este opusul lui Partial.

Prompt
Arată tipurile utilitare mapate predefinite aplicate unei singure interfețe. Declară o interfață User cu id: number, name: string, email: string și isAdmin: boolean, apoi creează alias-uri de tip folosind Partial<User>, Required<Partial<User>>, Readonly<User>, Pick<User, "email" | "id">, Omit<User, "id" | "isAdmin"> și Record<"admin" | "user" | "guest", string>, fiecare urmat de un comentariu care scrie explicit tipul obiect echivalent. Fișierul doar declară tipuri și nu afișează nimic.
Ieșire: program TypeScript și rezultatul capturat

Crearea de tipuri mapate proprii

Poți scrie propriile tipuri mapate generice, ca să transformi tipurile exact așa cum ai nevoie.

Exemplu

StringifyProperties<T> transformă fiecare proprietate într-un string. Validator<T> transformă fiecare proprietate într-o funcție care primește o valoare de tipul acelei proprietăți (T[P]) și returnează un boolean, așa că productValidator trebuie să ofere câte o verificare pentru fiecare proprietate a lui Product.

Prompt
Arată două tipuri mapate generice proprii, construite pe o interfață Product (id: number, name: string, price: number, inStock: boolean). Scrie StringifyProperties<T>, care transformă fiecare proprietate în string, și Validator<T>, care transformă fiecare proprietate P într-o funcție (value: T[P]) => boolean. Aplică-l pe primul pentru a obține un tip StringProduct și folosește-l pe al doilea pentru a construi un obiect productValidator ale cărui verificări sunt: id mai mare decât 0, name nevid, price cel puțin 0 și inStock să fie de tip boolean. Nu se afișează nimic.
Ieșire: program TypeScript și rezultatul capturat

Modificarea modificatorilor de proprietate

Un tip mapat poate și să adauge sau să elimine modificatorii de proprietate readonly și ? (opțional). Scriind +readonly sau readonly adaugi modificatorul; scriind -readonly îl elimini. La fel funcționează și pentru ? cu -?.

Exemplu

Mutable<T> folosește -readonly pentru a elimina marcajul de doar citire de la fiecare proprietate a lui Configuration. RequiredProps<T> folosește -? pentru a face obligatorie fiecare proprietate opțională.

Prompt
Arată cum un tip mapat poate elimina modificatorii readonly și ? folosind -readonly și -?. Declară o interfață Configuration cu readonly apiKey: string, readonly apiUrl: string, timeout?: number și retries?: number. Scrie Mutable<T> (elimină readonly de la fiecare proprietate) și RequiredProps<T> (elimină ? de la fiecare proprietate), aplică-le pe fiecare pe Configuration ca MutableConfig și RequiredConfig și comentează după fiecare tipul obiect echivalent. Fișierul doar declară tipuri și nu afișează nimic.
Ieșire: program TypeScript și rezultatul capturat

Tipuri mapate avansate

Tipurile mapate devin și mai puternice când le combini cu tipuri condiționale. Tipul nou al fiecărei proprietăți poate atunci să depindă de cel vechi.

Exemplu

FormattedResponse<T> verifică fiecare proprietate cu T[P] extends number și convertește proprietățile numerice în string. StringPropsOnly<T> folosește o clauză as pentru a redenumi cheile: proprietățile care nu sunt șiruri sunt mapate la never, ceea ce le elimină din rezultat.

Prompt
Combină tipurile mapate cu tipurile condiționale pe o interfață ApiResponse (data: unknown, status: number, message: string, timestamp: number). Scrie FormattedResponse<T>, care transformă fiecare proprietate de tip number în string și le lasă neschimbate pe celelalte, și StringPropsOnly<T>, care folosește o clauză as de redenumire a cheilor pentru a păstra doar proprietățile al căror tip este string. Aplică-le pe amândouă pe ApiResponse și comentează tipurile rezultate. Nu se afișează nimic.
Ieșire: program TypeScript și rezultatul capturat

Idei principale

Tipurile mapate îți permit să transformi fiecare proprietate a unui tip într-un mod consecvent.

Concepte cheie:

  • Transformarea tipurilor: schimbă în bloc tipurile proprietăților
  • Modificatori de proprietate: adaugă sau elimină readonly și ?
  • Remaparea cheilor: redenumește sau filtrează proprietățile cu o clauză as
  • Compunere: combină tipurile mapate cu alte facilități TypeScript, cum ar fi tipurile condiționale

Cazuri de utilizare frecvente:

  • Crearea de versiuni doar pentru citire ale tipurilor
  • Transformarea tuturor proprietăților în opționale sau obligatorii
  • Transformarea tipurilor proprietăților (de exemplu în nullable sau readonly)
  • Filtrarea proprietăților după tipul lor
  • Crearea de funcții utilitare sigure din punctul de vedere al tipurilor