Tipuri speciale în TypeScript
TypeScript are mai multe tipuri speciale, fiecare cu propriul comportament în sistemul de tipuri.
Le folosești atunci când tipul unei valori nu este cunoscut dinainte sau când trebuie să lucrezi în siguranță cu valori JavaScript precum null.
Notă: Aceste tipuri speciale fac parte din sistemul de tipuri al TypeScript. Ele ajută la scrierea unui cod mai sigur și mai ușor de citit.
Tipul: any
any este cel mai flexibil tip din TypeScript.
Îi spune compilatorului să sară peste verificarea de tip pentru acea variabilă.
Poate fi util, dar folosește-l cu măsură — renunți astfel la siguranța tipurilor oferită de TypeScript.
Când să folosești any:
- Când migrezi cod JavaScript către TypeScript
- Când lucrezi cu conținut dinamic al cărui tip nu este cunoscut
- Când vrei să renunți la verificarea de tip într-un singur loc anume
Notă: any te poate scăpa de erori pentru că dezactivează verificarea de tip, dar TypeScript nu te mai poate proteja, iar uneltele care se bazează pe informațiile de tip, cum ar fi completarea automată, nu mai funcționează.
Ține minte, ar trebui evitat cu „orice” preț...
Exemplu fără any
Acest exemplu nu folosește any. Tipul lui u este dedus ca boolean, așa că atribuirea unui șir de caractere și transmiterea lui către Math.round sunt ambele erori.
any atunci când o variabilă este folosită ca tipuri diferite.
Declară u = true (dedus ca boolean), atribuie-i șirul de caractere „string”, apoi transmite u către Math.round — ambele linii trebuie să nu se compileze: „Type 'string' is not assignable to type 'boolean'” și „Argument of type 'boolean' is not assignable to parameter of type 'number'”.
Ieșire: program TypeScript și rezultatul capturat
let u = true;
u = "string"; // Eroare: Type 'string' is not assignable to type 'boolean'.
Math.round(u); // Eroare: Argument of type 'boolean' is not assignable to parameter of type 'number'.
Exemplu cu any
Dacă îi dai lui v tipul any, verificarea de tip este dezactivată, așa că același cod se compilează fără erori.
any dezactivează verificarea de tip.
Declară v: any = true, atribuie-i șirul de caractere „string”, apoi transmite v către Math.round — niciuna dintre linii nu produce o eroare și nu se afișează nimic.
Ieșire: program TypeScript și rezultatul capturat
let v: any = true;
v = "string"; // fără eroare, deoarece poate fi de tipul "any"
Math.round(v); // fără eroare, deoarece poate fi de tipul "any"
Tipul: unknown
unknown este varianta sigură din punctul de vedere al tipurilor a lui any.
Înseamnă „aceasta poate fi orice, deci trebuie să verifici ce este înainte de a o folosi”.
Diferențe importante între unknown și any:
unknowntrebuie verificat ca tip înainte de utilizare- Nu poți citi proprietățile unei valori
unknownfără o aserțiune de tip (o conversie) - Nu poți apela și nu poți construi o valoare de tip
unknown
TypeScript nu te lasă să folosești o valoare unknown până când nu i-ai verificat tipul, așa cum arată exemplul.
Când să folosești unknown:
- Când lucrezi cu date din surse externe (API-uri, date introduse de utilizator etc.)
- Când vrei siguranța tipurilor, dar ai nevoie și de flexibilitate
- Când migrezi de la JavaScript la TypeScript într-un mod sigur
Restrângerea tipului cu unknown: poți restrânge o valoare unknown la un tip concret folosind gărzi de tip precum typeof și Array.isArray, ca în fragmentul de cod de mai jos.
Exemplu
w acceptă un număr, un șir de caractere și un obiect. Apelarea directă a unei metode pe el este o eroare; după o verificare cu typeof și o conversie, apelul este permis și afișează mesajul său.
unknown acceptă orice valoare, dar trebuie verificat sau convertit înainte de utilizare.
Declară w: unknown = 1, reatribuie-i un șir de caractere, apoi un obiect cu o metodă runANonExistentMethod care afișează „Gândesc, deci exist” (convertește cu as la un tip obiect). Păstrează un apel direct comentat, care ar produce eroarea „Object is of type 'unknown'”, apoi protejează codul cu typeof w === 'object' && w !== null și apelează metoda printr-o conversie în interiorul lui if.
Ieșire: program TypeScript și rezultatul capturat
let w: unknown = 1;
w = "string"; // fără eroare
w = {
runANonExistentMethod: () => {
console.log("Gândesc, deci exist");
}
} as { runANonExistentMethod: () => void}
// Cum putem evita eroarea pentru codul comentat de mai jos, când nu cunoaștem tipul?
// w.runANonExistentMethod(); // Eroare: Object is of type 'unknown'.
if(typeof w === 'object' && w !== null) {
(w as { runANonExistentMethod: Function }).runANonExistentMethod();
}
// Deși trebuie să facem mai multe conversii, putem face o verificare în if pentru a ne asigura tipul și a avea o conversie mai sigură
Restrângerea lui unknown cu gărzi de tip
În interiorul fiecărei ramuri, TypeScript tratează value ca pe un string sau ca pe un tablou, deci membrii lui pot fi folosiți în siguranță.
function processValue(value: unknown) {
if (typeof value === 'string') {
// value is now treated as string
console.log(value.toUpperCase());
} else if (Array.isArray(value)) {
// value is now treated as any[]
console.log(value.length);
}
}
Tipul: never
never este tipul valorilor care nu apar niciodată.
El spune că ceva nu se întâmplă niciodată sau nu ar trebui să se întâmple niciodată.
Utilizări frecvente pentru never:
- Funcții care nu returnează niciodată (aruncă întotdeauna o eroare sau rulează la nesfârșit)
- Gărzi de tip care nu trec niciodată verificarea de tip
- Verificarea exhaustivității în uniuni discriminate
Fragmentele de cod de mai jos arată never în acțiune, iar exemplul arată ce se întâmplă dacă încerci să îi atribui o valoare.
Când să folosești never:
- Pentru funcții care nu vor returna niciodată o valoare
- În gărzi de tip care nu ar trebui să se potrivească niciodată
- Pentru verificarea exhaustivă a tipurilor în instrucțiuni
switch - În tipuri generice, pentru a marca anumite cazuri drept imposibile
Tipul never de bază
Nicio valoare nu poate fi atribuită tipului never, așa că atribuirea lui true este o eroare de compilare.
never.
Declară x: never și atribuie-i true — compilatorul trebuie să raporteze „Type 'boolean' is not assignable to type 'never'”.
Ieșire: program TypeScript și rezultatul capturat
let x: never = true; // Eroare: Type 'boolean' is not assignable to type 'never'.
Funcție care nu returnează niciodată
O funcție care aruncă întotdeauna o eroare poate declara tipul de retur never.
function throwError(message: string): never {
throw new Error(message);
}
Verificarea exhaustivității cu never
În ramura default, pentru shape nu ar trebui să mai rămână niciun caz, așa că atribuirea lui unei variabile never face ca TypeScript să semnaleze dacă o formă a fost uitată.
type Shape = Circle | Square | Triangle;
function getArea(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.sideLength ** 2;
default:
// TypeScript knows this should never happen
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
Tipul: undefined și null
În TypeScript, undefined și null au fiecare propriul tip, la fel ca string sau number.
În mod implicit, aceste valori pot fi atribuite oricărui alt tip. Poți schimba acest lucru cu verificările stricte de null din TypeScript.
Puncte importante despre undefined și null:
undefinedînseamnă că o variabilă a fost declarată, dar nu a primit niciodată o valoarenulleste o atribuire explicită care înseamnă „nicio valoare” sau „niciun obiect”- În TypeScript, ambele au propriile tipuri:
undefinedșinull - Cu
strictNullChecksactivat, trebuie să tratezi explicit aceste tipuri
Parametri și proprietăți opționale — un ? după numele unui parametru sau al unei proprietăți îl face opțional, ceea ce adaugă undefined la tipul său.
Operatorul de coalescență nulă și lanțul opțional — ?? oferă o valoare implicită doar atunci când o valoare este null sau undefined, iar ?. citește proprietăți imbricate fără a provoca o eroare atunci când ceva din lanț lipsește.
Important: Aceste tipuri sunt cele mai utile atunci când strictNullChecks este activat în tsconfig.json. Atunci null și undefined pot fi atribuite doar lor înseși și lui any.
Pentru a activa verificările stricte de null, adaugă "compilerOptions": { "strictNullChecks": true } în tsconfig.json.
Utilizare de bază
y are tipul undefined, iar z are tipul null.
undefined și null sunt tipuri de sine stătătoare în TypeScript.
Declară y cu tipul undefined conținând undefined și z cu tipul null conținând null. Nu se afișează nimic.
Ieșire: program TypeScript și rezultatul capturat
let y: undefined = undefined;
let z: null = null;
Parametri și proprietăți opționale
Un parametru opțional este implicit string | undefined, iar o proprietate opțională dintr-o interfață este același lucru cu number | undefined.
// Optional parameter (implicitly `string | undefined`)
function greet(name?: string) {
return `Hello, ${name || 'stranger'}`;
}
// Optional property in an interface
interface User {
name: string;
age?: number; // Same as `number | undefined`
}
Coalescență nulă și lanț opțional
?? revine la 'default' doar pentru null sau undefined, iar ?. citește în siguranță user.address.street.
// Nullish coalescing (??) - only uses default if value is null or undefined
const value = input ?? 'default';
// Optional chaining (?.) - safely access nested properties
const street = user?.address?.street;