Salt la conținutul principal
Modulul 3 · Lecția 2 din 26/14 în curs~15 min
Lecții din modul (2/2)

Generice fundamentale

Generics (programare generică) sunt una dintre cele mai puternice caracteristici ale TypeScript. Acestea vă permit să scrieți componente, funcții și interfețe flexibile și reutilizabile care pot funcționa cu diferite tipuri de date, menținând în același timp siguranța maximă a tipului și evitând utilizarea any.


Funcții generice

Gândiți-vă la un generic ca la o variabilă pentru tipuri. Să considerăm o funcție care returnează valoarea transmisă ca argument:

TS
function identity<T>(arg: T): T {
  return arg;
}

Litera T (prescurtare pentru Type) este un substituent pentru tip. Când apelăm identity, TypeScript captează tipul argumentului transmis și setează automat T la acel tip:

TS
const str = identity<string>('Hello'); // T is string
const num = identity(42); // T is number (automatically inferred!)

Interfețe și aliasuri generice

Genericurile pot fi, de asemenea, aplicate la interfețe și alias-uri de tip pentru a defini containere generice sau structuri de date:

TS
interface Box<T> {
  content: T;
}

const stringBox: Box<string> = { content: 'TypeScript' };
const numberBox: Box<number> = { content: 42 };

Parametri de tip multiplu

Putem defini funcții sau tipuri care utilizează mai multe variabile de tip (de exemplu, T și U):

TS
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

Constrângeri generice

Uneori vrem să limităm tipurile acceptate de un generic. Putem folosi cuvântul cheie extends pentru a adăuga o constrângere.

De exemplu, dacă dorim ca tipul generic să aibă întotdeauna o proprietate length (cum ar fi șiruri de caractere sau matrice):

TS
interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(arg: T): void {
  console.log(arg.length); // Safe! We know arg has 'length'
}

logLength('Hello'); // Valid
logLength([1, 2, 3]); // Valid
// logLength(42); // Error: number does not have a length property!

Încercați-l singur

Exercițiul 1: Funcția de identitate generică

Exercițiu#ts.m3.l2.e1
Încercări: 0Se încarcă…

Completați funcția de identitate generică astfel încât să accepte un parametru de valoare de tip generic T și să-l returneze fără modificare.

Se încarcă editorul...
Afișează indiciu

Tipul returnat trebuie să fie de același tip generic T ca și parametrul.

Soluție disponibilă după 3 încercări

Exercițiul 2: Box Wrapper generic

Exercițiu#ts.m3.l2.e2
Încercări: 0Se încarcă…

Definiți o interfață generică numită Box care acceptă un parametru de tip T și are o singură proprietate numită conținut de tip T.

Se încarcă editorul...
Afișează indiciu

Utilizați interfața Box<T> { conținut: T; } sintaxă.

Soluție disponibilă după 3 încercări

Exercițiul 3: Constrângere generică

Exercițiu#ts.m3.l2.e3
Încercări: 0Se încarcă…

Scrieți o funcție generică numită getLength care acceptă un parametru arg. arg trebuie să fie constrâns la o interfață care are o proprietate de lungime (număr). Funcția trebuie să returneze arg.length.

Se încarcă editorul...
Afișează indiciu

Declarați funcția ca getLength<T extins HasLength>(arg: T): număr și returnează arg.length.

Soluție disponibilă după 3 încercări

Exercițiul 4: Perechea generică

Exercițiu#ts.m3.l2.e4
Încercări: 0Se încarcă…

Definiți o interfață generică Pair<T, U> cu două proprietăți: prima de tip T și a doua de tip U. Apoi, creați o funcție generică makePair care acceptă primul (de tipul T) și al doilea (de tipul U) și returnează un obiect care implementează Pair<T, U>.

Se încarcă editorul...
Afișează indiciu

Utilizați sintaxa pentru doi parametri generici Pair<T, U> și definiți makePair în consecință.

Soluție disponibilă după 3 încercări