Tipi di unione e intersezione TypeScript

TypeScript fornisce potenti funzionalità di sistema di tipo che ti aiutano a scrivere codice più sicuro e prevedibile. Tra queste funzionalità ci sono i tipi di unione e intersezione, che offrono flessibilità nella definizione e gestione di tipi complessi. Questo articolo introduce questi concetti e fornisce esempi per illustrarne l'utilizzo.

Quali sono i tipi di unione?

I tipi di unione consentono a una variabile di contenere valori di tipi diversi. Ciò è utile quando è necessario rappresentare un valore che potrebbe essere di diversi tipi. I tipi di unione sono indicati utilizzando il simbolo | (pipe).

Definizione dei tipi di unione

Per definire un tipo di unione, è necessario specificare più tipi separati dal simbolo |:

let value: string | number;

value = "Hello, TypeScript"; // Valid
value = 42; // Valid
value = true; // Error: Type 'boolean' is not assignable to type 'string | number'

In questo esempio, la variabile value può essere una string o una number, ma non una boolean.

Utilizzo dei tipi unione nelle funzioni

I tipi unione sono particolarmente utili nelle funzioni in cui i parametri o i tipi di ritorno possono essere di tipi multipli:

function formatValue(value: string | number): string {
  if (typeof value === "string") {
    return value.toUpperCase();
  } else {
    return value.toFixed(2);
  }
}

console.log(formatValue("hello")); // Output: HELLO
console.log(formatValue(123.456)); // Output: 123.46

La funzione formatValue accetta un parametro che può essere una stringa o un numero e lo formatta di conseguenza.

Cosa sono i tipi di intersezione?

I tipi di intersezione consentono di combinare più tipi in uno. Ciò significa che un valore del tipo di intersezione soddisferà tutti i tipi nell'intersezione. I tipi di intersezione sono indicati utilizzando il simbolo & (e commerciale).

Definizione dei tipi di intersezione

Per definire un tipo di intersezione, è necessario specificare più tipi separati dal simbolo &:

interface Person {
  name: string;
}

interface Employee {
  employeeId: number;
}

type EmployeePerson = Person & Employee;

const john: EmployeePerson = {
  name: "John Doe",
  employeeId: 1234
};

console.log(john.name); // Output: John Doe
console.log(john.employeeId); // Output: 1234

In questo esempio, il tipo EmployeePerson combina le interfacce Person e Employee, ottenendo un tipo che ha entrambe le proprietà name e employeeId.

Utilizzo dei tipi di intersezione nelle funzioni

I tipi di intersezione possono anche essere utilizzati nelle funzioni per richiedere più proprietà di tipo:

function printEmployeeDetails(employee: Person & Employee): void {
  console.log(`Name: ${employee.name}`);
  console.log(`Employee ID: ${employee.employeeId}`);
}

const jane: EmployeePerson = {
  name: "Jane Smith",
  employeeId: 5678
};

printEmployeeDetails(jane);
// Output:
// Name: Jane Smith
// Employee ID: 5678

La funzione printEmployeeDetails richiede un argomento che soddisfi entrambi i tipi Person e Employee.

Combinazione di tipi di unione e intersezione

È possibile combinare i tipi di unione e intersezione per creare definizioni di tipi complessi:

type Shape = Circle | Rectangle;

interface Circle {
  kind: "circle";
  radius: number;
}

interface Rectangle {
  kind: "rectangle";
  width: number;
  height: number;
}

function getArea(shape: Shape): number {
  if (shape.kind === "circle") {
    return Math.PI * shape.radius * shape.radius;
  } else {
    return shape.width * shape.height;
  }
}

const myCircle: Circle = { kind: "circle", radius: 10 };
const myRectangle: Rectangle = { kind: "rectangle", width: 20, height: 30 };

console.log(getArea(myCircle)); // Output: 314.159...
console.log(getArea(myRectangle)); // Output: 600

In questo esempio, il tipo Shape è un'unione di Circle e Rectangle, e la funzione getArea gestisce entrambi i tipi di conseguenza.

Conclusione

I tipi di unione e intersezione in TypeScript forniscono potenti modi per gestire e combinare i tipi, offrendo flessibilità e precisione nelle definizioni dei tipi. I tipi di unione consentono a una variabile di essere uno di diversi tipi, mentre i tipi di intersezione combinano più tipi in uno. Utilizzando queste funzionalità, puoi creare applicazioni più robuste e sicure per i tipi.

Fai pratica utilizzando i tipi di unione e intersezione per acquisire familiarità con le loro funzionalità e migliorare le tue competenze di programmazione TypeScript.