Saltar al contenido principal
eLearner.app
Módulo 2 · Lección 2 de 24/14 en el curso~15 min
Lecciones del módulo (2/2)

Uniones y Estrechamiento

En el mundo real, las variables y las respuestas de las APIs no siempre tienen un único tipo fijo. TypeScript ofrece los Tipos Unión (Union Types) para gestionar la variabilidad, y el Estrechamiento de Tipos (Type Narrowing) para operar de forma segura con ellos en tiempo de ejecución.


Tipos Unión (Union Types)

Un tipo unión permite que una variable acepte valores de diferentes tipos. Se expresa mediante el símbolo de la barra vertical (|):

TS
let result: number | string;
result = 42; // Valido
result = 'Errore 404'; // Valido

Sin embargo, cuando trabajamos con un tipo unión, no podemos llamar directamente a métodos que pertenezcan a uno solo de los tipos (por ejemplo, no podemos hacer .toUpperCase() si la variable también puede ser un number). Primero debemos "estrechar" el tipo.


Estrechamiento de Tipos (Type Narrowing)

El Type Narrowing es el proceso por el cual TypeScript analiza las estructuras de control de flujo (como if o switch) para deducir un tipo más específico para una variable en tiempo de ejecución.

Existen diferentes formas de realizar el narrowing:

1. Operador typeof

Ideal para distinguir tipos primitivos:

TS
function printLength(value: string | number) {
  if (typeof value === 'string') {
    // Qui TypeScript sa che 'value' è una stringa
    console.log(value.length);
  } else {
    // Qui TypeScript sa che 'value' è un numero
    console.log(value.toFixed(2));
  }
}

2. Operador in

Se utiliza para verificar la presencia de una propiedad específica en un objeto:

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

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

Uniones Discriminadas (Discriminated Unions)

El patrón de las Uniones Discriminadas consiste en crear objetos que comparten una propiedad común con un valor literal único (llamado discriminador). TypeScript reconoce este discriminador y realiza el narrowing automático dentro de los bloques condicionales.

TS
interface SuccessResponse {
  status: 'success'; // Discriminatore letterale
  data: string;
}

interface ErrorResponse {
  status: 'error'; // Discriminatore letterale
  errorMessage: string;
}

type ApiResponse = SuccessResponse | ErrorResponse;

function handleResponse(response: ApiResponse) {
  if (response.status === 'success') {
    console.log('Dati ricevuti:', response.data);
  } else {
    console.error('Si è verificato un errore:', response.errorMessage);
  }
}

Pruébalo tú

Ejercicio 1: Unión de Tipos

Ejercicio#ts.m2.l2.e1
Intentos: 0Cargando...

Declara una variable llamada id que pueda ser tanto un número como una cadena. Inicialízala primero con el número 101, luego asigna el valor de cadena 'USER-101'.

Cargando editor...
Mostrar pista

Usa el operador | para unir number y string en la declaración de la variable let.

Solución disponible después de 3 intentos

Ejercicio 2: Type Narrowing Básico

Ejercicio#ts.m2.l2.e2
Intentos: 0Cargando...

Crea una función llamada formatInput que acepte un parámetro input de tipo cadena o número. Si input es una cadena, devuelve input convertido a mayúsculas. Si es un número, devuelve input multiplicado por 2. Especifica los tipos de forma explícita.

Cargando editor...
Mostrar pista

Usa typeof input === 'string' dentro de un blocco if para distinguir el comportamiento.

Solución disponible después de 3 intentos

Ejercicio 3: Narrowing con 'in'

Ejercicio#ts.m2.l2.e3
Intentos: 0Cargando...

Dadas las dos interfaces Car (con el método drive) y Boat (con el método sail), escribe una función llamada moveVehicle que acepte un parámetro vehicle de tipo Car o Boat. Si vehicle tiene la propiedad drive, ejecuta el método drive(). De lo contrario, ejecuta el método sail().

Cargando editor...
Mostrar pista

Usa el operador in de la forma 'drive' in vehicle para hacer el narrowing de la interfaz.

Solución disponible después de 3 intentos

Ejercicio 4: Unión Discriminada Shape

Ejercicio#ts.m2.l2.e4
Intentos: 0Cargando...

Define un tipo Shape que sea la unión de dos tipos: Circle y Square. Circle tiene una propiedad kind establecida en 'circle' (valor literal) y un radius (número). Square tiene una propiedad kind establecida en 'square' (valor literal) y un side (número). Luego escribe una función getArea que acepte shape de tipo Shape y devuelva el área como número (para el círculo Math.PI * radius * radius, para el cuadrado side * side).

Cargando editor...
Mostrar pista

Usa shape.kind === 'circle' dentro de getArea para discriminar el tipo y calcular el área correcta.

Solución disponible después de 3 intentos