Recursión a nivel de tipos
Recorra tipos mediante tipos condicionales recursivos.
Recursión a nivel de tipos es una lección gratuita de TypeScript Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de TypeScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de TypeScript Academy incluye 4 lecciones en total.
Recursión en tipos
Un tipo condicional puede referirse a sí mismo. Esto proporciona bucles al lenguaje de tipos. La mayoría de las recursiones a nivel de tipos recorren una tupla elemento a elemento, extrayendo la cabeza y recurriendo sobre la cola.
type Length<T extends unknown[]> =
T extends [unknown, ...infer Rest]
? Length<Rest>
: 0;
// (this counts down to a base case)El caso base
Toda recursión necesita una condición de parada. En las tuplas suele ser la tupla vacía. Cuando el patrón [head, ...rest] deja de coincidir, ha llegado al final y devuelve un resultado fijo.
type IsEmpty<T extends unknown[]> =
T extends [] ? true : false;
type A = IsEmpty<[]>; // true
type B = IsEmpty<[1, 2]>; // falseCabeza y cola
La operación fundamental consiste en dividir una tupla en su primer elemento y la tupla restante, utilizando infer con el patrón de propagación.
type Head<T extends unknown[]> = T extends [infer H, ...unknown[]] ? H : never;
type Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : [];
type A = Head<[1, 2, 3]>; // 1
type B = Tail<[1, 2, 3]>; // [2, 3]Procesar elemento a elemento
Combine la cabeza, la cola y la recursión para transformar una tupla completa. ToStrings reconstruye la tupla y reemplaza cada tipo de elemento por string.
type ToStrings<T extends unknown[]> =
T extends [infer H, ...infer R]
? [string, ...ToStrings<R>]
: [];
type A = ToStrings<[1, true, 3]>; // [string, string, string]El patrón del acumulador
A menudo se construye el resultado en un parámetro adicional llamado acumulador. Comienza vacío y crece en cada paso. Esto evita volver a recorrer la estructura y es la técnica estándar para los bucles a nivel de tipos.
type Reverse<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? Reverse<R, [H, ...Acc]>
: Acc;
type A = Reverse<[1, 2, 3]>; // [3, 2, 1]Recorrer el acumulador
Trace Reverse<[1,2,3]>:
- Paso 1: H=1, Acc pasa a ser [1]
- Paso 2: H=2, Acc pasa a ser [2,1]
- Paso 3: H=3, Acc pasa a ser [3,2,1]
- La tupla está vacía; devolver Acc = [3,2,1]
El acumulador transporta el resultado en cada llamada recursiva.
type R = Reverse<["a", "b"]>; // ["b", "a"]Recursión sobre uniones
También puede recurrir para unir una unión de cadenas. Aquí concatenamos los elementos de una tupla en un único tipo literal de cadena, separados por un delimitador.
Notación: en TypeScript real, los tipos literales de plantilla se escriben con cadenas delimitadas por comillas invertidas que contienen marcadores dollar-brace. En estos fragmentos mostramos ese patrón como Tpl<...>, enumerando cada parte en orden; por ejemplo, una plantilla con comillas invertidas que coincide con el prefijo literal seguido de Rest aparece como Tpl<'prefix', infer Rest>.
type Join<T extends string[], Sep extends string = ','> =
T extends [infer H extends string, ...infer R extends string[]]
? R extends []
? H
: Tpl<H, Sep, Join<R, Sep>>
: '';
// Tpl<H, Sep, ...> builds a template literal type joining the parts
type A = Join<['a', 'b', 'c']>; // 'a,b,c'Contar con recursión
La recursión junto con un acumulador permite contar. Construya una tupla de unknown con la misma longitud que la entrada y, después, lea su length. Utilizará esta técnica con frecuencia en el curso de aritmética.
type Count<T extends unknown[], Acc extends unknown[] = []> =
T extends [unknown, ...infer R]
? Count<R, [unknown, ...Acc]>
: Acc["length"];
type A = Count<["x", "y", "z"]>; // 3Filtrar con recursión
Recorra una tupla y conserve solo los elementos que coincidan con una condición, descartando los demás. Omita un elemento sin añadirlo al acumulador.
type KeepStrings<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? H extends string
? KeepStrings<R, [...Acc, H]>
: KeepStrings<R, Acc>
: Acc;
type A = KeepStrings<[1, "a", 2, "b"]>; // ["a", "b"]Límites de profundidad de la recursión
El compilador limita la profundidad de la recursión (históricamente alrededor de 50, aunque las optimizaciones de recursión de cola permiten más en algunos patrones). Con tuplas muy grandes puede aparecer Type instantiation is excessively deep. Utilice el estilo con acumulador (de cola) para aumentar el límite.
type Repeat<T, N extends number, Acc extends T[] = []> =
Acc["length"] extends N ? Acc : Repeat<T, N, [...Acc, T]>;
type A = Repeat<0, 3>; // [0, 0, 0]Integrarlo todo
La división entre cabeza y cola, un caso base y un acumulador son los tres ingredientes de casi todos los bucles a nivel de tipos. Con ellos puede mapear, filtrar, invertir, contar y unir tuplas por completo dentro del sistema de tipos.
type MapToPairs<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? MapToPairs<R, [...Acc, [H, H]]>
: Acc;
type A = MapToPairs<[1, 2]>; // [[1, 1], [2, 2]]Comprobación rápida
Compruebe cuánto entiende del patrón del acumulador.
Resumen
Ahora puede escribir bucles a nivel de tipos.
- Los condicionales autorreferentes crean recursión.
- Divida las tuplas en
[H, ...R]y recurra sobre la cola. - Un caso base (una tupla vacía) detiene el bucle.
- Un acumulador construye el resultado y permite una recursión profunda.
A continuación: cómo se comportan especialmente los condicionales con las uniones.
Preguntas frecuentes
¿La lección «Recursión a nivel de tipos» es gratis?
Sí — el texto completo de «Recursión a nivel de tipos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de TypeScript Academy, actualiza a CoddyKit PRO. El curso de TypeScript Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Recursión a nivel de tipos»?
Recorra tipos mediante tipos condicionales recursivos. Practicas TypeScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar TypeScript Academy?
No se requiere experiencia previa. TypeScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Recursión a nivel de tipos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de TypeScript Academy?
Sí. Cada lección de TypeScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Los tipos como lenguaje de computación
- Condicionales a nivel de tipos
- Recursión a nivel de tipos
- Tipos condicionales distributivos