0Pricing
TypeScript Academy · Lezione

Ricorsione a livello di tipo

Iteri sui tipi utilizzando tipi condizionali ricorsivi.

Ricorsione a livello di tipo è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 4 lezioni in totale.

Ricorsione nei tipi

Un tipo condizionale può fare riferimento a sé stesso. In questo modo il linguaggio dei tipi ottiene dei cicli. La maggior parte della ricorsione a livello di tipo attraversa una tupla un elemento alla volta, rimuovendo la testa e richiamandosi ricorsivamente sulla coda.

type Length<T extends unknown[]> =
  T extends [unknown, ...infer Rest]
    ? Length<Rest>
    : 0;
// (this counts down to a base case)

Il caso base

Ogni ricorsione ha bisogno di una condizione di arresto. Per le tuple, di solito è la tupla vuota. Quando lo schema [head, ...rest] non corrisponde più, significa che è stata raggiunta la fine e si restituisce un risultato fisso.

type IsEmpty<T extends unknown[]> =
  T extends [] ? true : false;

type A = IsEmpty<[]>;     // true
type B = IsEmpty<[1, 2]>; // false

Testa e coda

Il passaggio fondamentale consiste nel dividere una tupla nel primo elemento e nella tupla rimanente, usando infer con lo schema spread.

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]

Elaborazione elemento per elemento

Combini testa, coda e ricorsione per trasformare un'intera tupla. ToStrings ricostruisce la tupla, sostituendo ogni tipo di elemento con string.

type ToStrings<T extends unknown[]> =
  T extends [infer H, ...infer R]
    ? [string, ...ToStrings<R>]
    : [];

type A = ToStrings<[1, true, 3]>; // [string, string, string]

Lo schema dell'accumulatore

Spesso si costruisce il risultato in un parametro aggiuntivo chiamato accumulatore. Inizia vuoto e cresce a ogni passaggio. In questo modo si evita di attraversare nuovamente la struttura ed è la tecnica standard per i cicli a livello di tipo.

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]

Attraversamento dell'accumulatore

Segua Reverse<[1,2,3]>:

  • Passo 1: H=1, Acc diventa [1]
  • Passo 2: H=2, Acc diventa [2,1]
  • Passo 3: H=3, Acc diventa [3,2,1]
  • Tupla vuota, restituisce Acc = [3,2,1]

L'accumulatore trasporta la risposta in ogni chiamata ricorsiva.

type R = Reverse<["a", "b"]>; // ["b", "a"]

Ricorsione sulle unioni

Può anche usare la ricorsione per concatenare un'unione di stringhe. Qui concateniamo gli elementi della tupla in un unico tipo letterale stringa, separati da un delimitatore.

Notazione: TypeScript reale scrive i tipi letterali template con stringhe delimitate da backtick che contengono segnaposto dollaro-graffe. In questi frammenti mostriamo questo schema come Tpl<...>, elencando ogni parte nell'ordine; ad esempio, un template con backtick che corrisponde al prefisso letterale seguito da Rest appare come 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'

Conteggio con la ricorsione

La ricorsione combinata con un accumulatore consente di contare. Costruisca una tupla di unknown della stessa lunghezza dell'input, quindi in seguito ne legga la proprietà length. Userà spesso questa tecnica nel corso sull'aritmetica.

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"]>; // 3

Filtraggio con la ricorsione

Attraversi una tupla e conservi solo gli elementi che corrispondono a una condizione, eliminando gli altri. Per saltare un elemento, non lo aggiunga all'accumulatore.

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"]

Limiti della profondità ricorsiva

Il compilatore limita la profondità della ricorsione (storicamente intorno a 50, anche se le ottimizzazioni della ricorsione in coda consentono di superare questo limite in alcuni schemi). Con tuple molto grandi potrebbe comparire l'errore L'istanziazione del tipo è eccessivamente profonda. Usi lo stile con accumulatore, cioè la ricorsione in coda, per aumentare il limite.

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]

Mettere tutto insieme

La suddivisione in testa e coda, un caso base e un accumulatore sono i tre ingredienti di quasi ogni ciclo a livello di tipo. Con questi elementi può mappare, filtrare, invertire, contare e concatenare tuple interamente nel sistema dei tipi.

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]]

Verifica rapida

Metta alla prova la Sua comprensione dello schema dell'accumulatore.

Riepilogo

Ora può scrivere cicli a livello di tipo.

  • I condizionali autoreferenziali creano la ricorsione.
  • Divida le tuple in [H, ...R] e ricorra sulla coda.
  • Un caso base (la tupla vuota) arresta il ciclo.
  • Un accumulatore costruisce il risultato e consente una ricorsione profonda.

Successivamente: il comportamento speciale dei condizionali sulle unioni.

Domande Frequenti

La lezione «Ricorsione a livello di tipo» è gratuita?

Sì — il testo completo di «Ricorsione a livello di tipo» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 4 lezioni in totale.

Cosa imparerò in «Ricorsione a livello di tipo»?

Iteri sui tipi utilizzando tipi condizionali ricorsivi. Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare TypeScript Academy?

Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Ricorsione a livello di tipo»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?

Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. I tipi come linguaggio di calcolo
  2. Condizionali a livello di tipo
  3. Ricorsione a livello di tipo
  4. Tipi condizionali distributivi
← Torna a TypeScript Academy