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

Uniri și îngustare

În lumea reală, variabilele și răspunsurile API nu au întotdeauna un singur tip fix. TypeScript oferă Tipuri de unire pentru a gestiona variabilitatea și Reducerea tipului pentru a opera în siguranță pe acestea în timpul execuției.


Tipuri de uniuni

Un tip de unire permite unei variabile să accepte valori de diferite tipuri. Este exprimat folosind simbolul barei verticale (|):

TS
let result: number | string;
result = 42; // Valid
result = 'Error 404'; // Valid

Cu toate acestea, atunci când lucrăm cu un tip de uniune, nu putem apela direct metode care aparțin doar unuia dintre tipuri (de exemplu, nu putem apela .toUpperCase() dacă variabila poate fi și o number). Mai întâi trebuie să „îngustăm” tipul.


Tip îngustare

Type Narrowing este procesul în care TypeScript analizează structurile fluxului de control (cum ar fi if sau switch) pentru a deduce un tip mai specific pentru o variabilă în timpul execuției.

Există mai multe moduri de a efectua îngustarea:

1. Operatorul typeof

Ideal pentru a distinge tipurile primitive:

TS
function printLength(value: string | number) {
  if (typeof value === 'string') {
    // TypeScript knows 'value' is a string here
    console.log(value.length);
  } else {
    // TypeScript knows 'value' is a number here
    console.log(value.toFixed(2));
  }
}

2. Operatorul in

Folosit pentru a verifica dacă o anumită proprietate există pe un obiect:

TS
interface Fish {
  swim: () => void;
}
interface Bird {
  fly: () => void;
}

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    animal.swim(); // Narrowing to Fish
  } else {
    animal.fly(); // Narrowing to Bird
  }
}

Sindicate discriminate

Modelul Uniuni discriminate constă în crearea de obiecte care au o proprietate comună cu o valoare literală unică (numită discriminator). TypeScript recunoaște acest discriminator și restrânge automat tipul în blocurile condiționate.

TS
interface SuccessResponse {
  status: 'success'; // Literal discriminator
  data: string;
}

interface ErrorResponse {
  status: 'error'; // Literal discriminator
  errorMessage: string;
}

type ApiResponse = SuccessResponse | ErrorResponse;

function handleResponse(response: ApiResponse) {
  if (response.status === 'success') {
    console.log('Data received:', response.data);
  } else {
    console.error('An error occurred:', response.errorMessage);
  }
}

Încercați-l singur

Exercițiul 1: Tipuri de unire

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

Declarați o variabilă numită id care poate fi fie un număr, fie un șir. Inițializați-l mai întâi cu numărul 101, apoi atribuiți valoarea șirului „USER-101”.

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

Utilizați | operator pentru a uni numărul și șirul în declarația variabilei let.

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

Exercițiul 2: Îngustarea tipului de bază

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

Creați o funcție numită formatInput care acceptă o intrare de parametru de tip șir sau număr. Dacă intrarea este un șir, returnați intrarea convertită în majuscule. Dacă este un număr, returnați intrarea înmulțită cu 2. Specificați în mod explicit tipurile.

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

Utilizați typeof input === „șir” în interiorul unui bloc if pentru a ramifica comportamentul.

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

Exercițiul 3: Îngustarea cu „în”

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

Având în vedere cele două interfețe Car (cu metoda drive) și Boat (cu metoda sail), scrieți o funcție numită moveVehicle care acceptă un parametru vehicul de tip Car sau Boat. Dacă vehiculul are proprietatea drive, executați metoda drive(). În caz contrar, executați metoda sail().

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

Utilizați operatorul în forma „conduceți” în vehicul pentru a restrânge interfața.

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

Exercițiul 4: Forma de uniune discriminată

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

Definiți un tip Formă care este unirea a două tipuri: Cerc și Pătrat. Cercul are o proprietate tip setată la „cerc” (valoare literală) și o rază (număr). Pătratul are o proprietate tip setată la „pătrat” (valoare literală) și o latură (număr). Apoi scrieți o funcție getArea care acceptă forma de tip Shape și returnează aria ca număr (pentru cerc Math.PI * rază * rază, pentru latura pătrată * latura).

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

Utilizați shape.kind === „cerc” în interiorul getArea pentru a discrimina tipul și a calcula zona corectă.

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