Tipos condicionales de TypeScript

Los tipos condicionales en TypeScript proporcionan una forma de crear tipos que dependen de una condición. Permiten una mayor flexibilidad y expresividad en las definiciones de tipos, lo que hace posible modelar relaciones de tipos complejas de una manera clara y concisa. Este artículo explora cómo funcionan los tipos condicionales en TypeScript y proporciona ejemplos para ilustrar su uso.

¿Qué son los tipos condicionales?

Los tipos condicionales permiten la creación de tipos que se seleccionan en función de una condición. Son similares a las instrucciones condicionales en programación, pero funcionan a nivel de tipo. La sintaxis básica de un tipo condicional es:

type ConditionalType = T extends U ? X : Y;

En esta sintaxis:

  • T es el tipo que se está comprobando.
  • U es el tipo con el que se realizará la comparación.
  • X es el tipo devuelto si T extiende U.
  • Y es el tipo devuelto si T no extiende U.

Ejemplo básico de tipos condicionales

A continuación se muestra un ejemplo simple de un tipo condicional que devuelve diferentes tipos según si un tipo determinado es una cadena o no:

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

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

En este ejemplo, IsString comprueba si T extiende string. Si es así, el resultado es "String"; de lo contrario, es "Not a string".

Uso de tipos condicionales con tipos genéricos

Los tipos condicionales también se pueden utilizar con tipos genéricos para crear definiciones de tipos más flexibles y reutilizables. Por ejemplo, un tipo que extrae el tipo de retorno de una función:

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

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

type Result = ReturnType;  // Result is string

En este ejemplo, ReturnType utiliza la palabra clave infer para inferir el tipo de retorno R del tipo de función T. Si T es un tipo de función, ReturnType será el tipo de retorno; de lo contrario, el valor predeterminado es never.

Tipos condicionales con tipos de unión

Los tipos condicionales también pueden funcionar con tipos de unión para manejar múltiples tipos posibles. Por ejemplo, distinguir entre diferentes miembros de la unión:

type ExtractString = T extends string ? T : never;

type UnionType = string | number | boolean;

type Result = ExtractString;  // Result is string

En este ejemplo, ExtractString extrae string de un tipo de unión UnionType, lo que da como resultado string.

Tipos condicionales con asignaciones de tipos

Los tipos condicionales se pueden combinar con asignaciones de tipos para crear transformaciones de tipos más complejas. Por ejemplo, la asignación de una matriz de tipos para aplicar un tipo condicional:

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]

En este ejemplo, MapArray mapea cada elemento de la matriz T y aplica un tipo condicional a cada elemento, lo que da como resultado una matriz donde solo se conservan los elementos de cadena.

Conclusión

Los tipos condicionales en TypeScript son una herramienta poderosa para crear definiciones de tipos flexibles y expresivas. Al aprovechar los tipos condicionales, los desarrolladores pueden modelar relaciones de tipos complejas, manejar varios escenarios y mejorar la seguridad de tipos en su código TypeScript. Comprender cómo usar los tipos condicionales de manera efectiva puede mejorar significativamente la capacidad de escribir código TypeScript sólido y fácil de mantener.