Tipuri condiționale TypeScript

Tipurile condiționate din TypeScript oferă o modalitate de a crea tipuri care depind de o condiție. Ele permit o mai mare flexibilitate și expresivitate în definițiile tipurilor, făcând posibilă modelarea relațiilor de tip complexe într-o manieră clară și concisă. Acest articol explorează cum funcționează tipurile condiționate în TypeScript și oferă exemple pentru a ilustra utilizarea lor.

Ce sunt tipurile condiționate?

Tipurile condiționate permit crearea de tipuri care sunt selectate pe baza unei condiții. Ele sunt similare cu instrucțiunile condiționate din programare, dar funcționează la nivel de tip. Sintaxa de bază a unui tip condiționat este:

type ConditionalType = T extends U ? X : Y;

În această sintaxă:

  • T este tipul care se verifică.
  • U este tipul cu care se compară.
  • X este tipul returnat dacă T extinde U.
  • Y este tipul returnat dacă T nu extinde U.

Exemplu de bază de tipuri condiționale

Iată un exemplu simplu de tip condiționat care returnează diferite tipuri în funcție de faptul dacă un anumit tip este un șir sau nu:

type IsString = T extends string ? "String" : "Not a string";

type Result1 = IsString;  // Result1 is "String"
type Result2 = IsString;  // Result2 is "Not a string"

În acest exemplu, IsString verifică dacă T extinde string. Dacă da, rezultatul este "String"; altfel, este "Not a string".

Utilizarea tipurilor condiționate cu tipurile generice

Tipurile condiționate pot fi utilizate și cu tipurile generice pentru a crea definiții de tip mai flexibile și mai reutilizabile. De exemplu, un tip care extrage tipul returnat al unei funcții:

type ReturnType = T extends (...args: any[]) => infer R ? R : never;

type FunctionType = (x: number) => string;

type Result = ReturnType;  // Result is string

În acest exemplu, ReturnType folosește cuvântul cheie infer pentru a deduce tipul de returnare R al tipului de funcție T. Dacă T este un tip de funcție, ReturnType va fi tipul de returnare; în caz contrar, implicit este never.

Tipuri condiționale cu tipuri de uniuni

Tipurile condiționate pot funcționa și cu tipuri de uniuni pentru a gestiona mai multe tipuri posibile. De exemplu, diferențierea între diferiți membri de sindicat:

type ExtractString = T extends string ? T : never;

type UnionType = string | number | boolean;

type Result = ExtractString;  // Result is string

În acest exemplu, ExtractString extrage string dintr-un tip de uniune UnionType, rezultând string.

Tipuri condiționate cu mapări de tip

Tipurile condiționate pot fi combinate cu mapările de tip pentru a crea transformări de tip mai complexe. De exemplu, maparea peste o serie de tipuri pentru a aplica un tip condiționat:

type MapArray = {
  [K in keyof T]: T[K] extends string ? T[K] : never;
};

type ArrayType = [string, number, boolean];

type MappedArray = MapArray;  // MappedArray is [string, never, never]

În acest exemplu, MapArray mapează fiecare element al matricei T și aplică un tip condiționat fiecărui element, rezultând o matrice în care sunt păstrate doar elemente șir.

Concluzie

Tipurile condiționate din TypeScript sunt un instrument puternic pentru crearea definițiilor de tip flexibile și expresive. Folosind tipurile condiționate, dezvoltatorii pot modela relații de tip complexe, pot gestiona diverse scenarii și pot îmbunătăți siguranța tipului în codul lor TypeScript. Înțelegerea modului de utilizare eficientă a tipurilor condiționate poate îmbunătăți semnificativ capacitatea de a scrie cod TypeScript robust și care poate fi întreținut.