tipo-never-typescript

Uso de Never en TypeScript

El tipo never en TypeScript representa el conjunto de valores para las funciones que nunca retornan un valor válido.

Esto generalmente significa que la función arroja una excepción o que entra en un bucle infinito y nunca completa su ejecución de manera normal.

Aunque es menos común que tipos como string, number, o boolean, el tipo never tiene un rol importante en la gestión de casos que no deben ocurrir (como errores o situaciones inalcanzables).

Algunas características del tipo never son:

  • No tiene valores: never no admite valores de ningún tipo.
  • Subtipo de todos los tipos: never es subtipo de cualquier otro tipo. Esto significa que never se puede asignar a cualquier otro tipo, pero no al revés.

Cómo usar el tipo never

El tipo never se usa principalmente en dos contextos:

  • Funciones que lanzan excepciones o entran en bucles infinito
  • En las estructuras de control de flujo para manejar casos inalcanzables.

Vamos a verlo con unos ejemplos,

Funciones que lanzan excepciones

function lanzarError(mensaje: string): never {
    throw new Error(mensaje);
}

lanzarError("Se ha producido un error crítico");

En este ejemplo, la función lanzarError toma un mensaje de error como parámetro y lanza una excepción. Dado que esta función nunca completa su ejecución normalmente (en lugar de devolver un valor, siempre lanza un error), su tipo de retorno es never.

Funciones con bucles infinitos

function bucleInfinito(): never {
    while (true) {
        // El bucle nunca termina
    }
}

La función bucleInfinito entra en un bucle que nunca termina, por lo que no puede devolver ningún valor ni alcanzar una conclusión normal. Por lo tanto, su tipo de retorno es never.

Casos inalcanzables en estructuras de control de flujo

El tipo never también se utiliza en la verificación de exhaustividad para asegurar que todos los casos posibles se han manejado en una estructura de control de flujo, como un switch.

type Animal = "Perro" | "Gato" | "Pájaro";

function describirAnimal(animal: Animal): string {
    switch (animal) {
        case "Perro":
            return "Es un perro";
        case "Gato":
            return "Es un gato";
        case "Pájaro":
            return "Es un pájaro";
        default:
            // Aquí, el tipo de `animal` debería ser `never`, ya que todos los casos posibles han sido manejados
            const _: never = animal;
            throw new Error("Tipo de animal no esperado");
    }
}

En este ejemplo,

  • El caso default en el switch debería manejar cualquier valor que no haya sido cubierto por los casos anteriores
  • La asignación de never a la variable _ garantiza que el compilador de TypeScript verifique que todos los casos posibles están cubiertos
  • Si se añaden más tipos a Animal y no se actualizan los casos del switch, TypeScript generará un error