Profondità e limiti della ricorsione
Comprenda i vincoli di TypeScript sulla profondità della ricorsione.
Profondità e limiti della ricorsione è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 4 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.
TypeScript ha limiti per la ricorsione
I tipi ricorsivi sono potenti, ma il verificatore dei tipi limita la profondità con cui può istanziarli. Se raggiunge il limite, viene restituito un errore di profondità.
// Excessively deep recursive types can produce:
// "Type instantiation is excessively deep and possibly infinite."Da dove provengono gli errori di profondità
I tipi condizionali che ricorsivamente non presentano un caso base chiaro e progressivamente ridotto possono entrare in un ciclo, soprattutto se combinati con grandi unioni o con la costruzione di tuple.
type Repeat<N extends number, Acc extends unknown[] = []> =
Acc["length"] extends N ? Acc : Repeat<N, [...Acc, unknown]>;
// Large N can exceed the instantiation depth.
type Five = Repeat<5>;Una ricorsione limitata sicura
Mantenga la ricorsione superficiale e limitata. Costruire una tupla piccola va bene; il caso base Acc["length"] extends N la interrompe rapidamente.
type Tuple<N extends number, Acc extends unknown[] = []> =
Acc["length"] extends N ? Acc : Tuple<N, [...Acc, unknown]>;
type Three = Tuple<3>; // [unknown, unknown, unknown]
const t: Three = [1, 2, 3];
console.log(t.length);Pattern di tipi ricorsivi in coda
TypeScript ottimizza alcuni tipi condizionali ricorsivi in coda trasportando un accumulatore, consentendo una ricorsione più profonda rispetto al semplice annidamento.
type Reverse<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer Head, ...infer Tail]
? Reverse<Tail, [Head, ...Acc]>
: Acc;
type R = Reverse<[1, 2, 3]>; // [3, 2, 1]
const r: R = [3, 2, 1];
console.log(r);Perché gli accumulatori sono utili
Passare i risultati attraverso un accumulatore mantiene la ricorsione in posizione di coda, che TypeScript può espandere in modo più efficiente rispetto a condizioni profondamente annidate.
type Join<T extends string[], Acc extends string = ""> =
T extends [infer H extends string, ...infer R extends string[]]
? Join<R, Acc extends "" ? H : Acc>
: Acc;
type First = Join<["a", "b", "c"]>; // "a"
const f: First = "a";
console.log(f);Evitare la ricorsione non in coda
Racchiudere la chiamata ricorsiva in un'altra operazione sul tipo interrompe la posizione di coda e può far raggiungere prima i limiti. Preferisca invece trasportare lo stato in un accumulatore.
// Non-tail (can be costly): builds nesting around the recursive call
// type Bad<T> = T extends [infer H, ...infer R] ? [H, ...Bad<R>] : [];
// Tail-friendly alternative uses an accumulator parameter.
console.log("prefer accumulators");Limitare esplicitamente la profondità
Aggiunga un contatore della profondità affinché il tipo si interrompa dopo un numero fisso di livelli, rinunciando alla completezza in cambio della terminazione garantita.
type Flatten<T, Depth extends unknown[] = []> =
Depth["length"] extends 5
? T
: T extends (infer U)[]
? Flatten<U, [...Depth, unknown]>
: T;
type X = Flatten<number[][]>; // number
const x: X = 7;
console.log(x);La profondità pratica è solitamente sufficiente
I tipi ricorsivi di uso quotidiano, come liste collegate, alberi e JSON, non raggiungono mai il limite perché i dati istanziati sono superficiali. I limiti riguardano soprattutto i calcoli complessi a livello di tipo.
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const v: Json = { a: { b: { c: 1 } } }; // fine, shallow
console.log(v);Riconoscere il messaggio di errore
Quando visualizza "excessively deep and possibly infinite", cerchi un caso base mancante, un accumulatore in posizione non di coda oppure un input troppo grande.
// Fixes: add/tighten the base case, switch to tail recursion,
// reduce input size, or cap with a depth counter.
console.log("check base case and tail position");La ricorsione a runtime è separata
Questi limiti riguardano la ricorsione a livello di tipo. Le normali funzioni ricorsive sui tipi ricorsivi vengono eseguite a runtime e sono limitate solo dallo stack delle chiamate.
type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function count<T>(n: TreeNode<T>): number {
return 1 + n.children.reduce((a, c) => a + count(c), 0);
}
console.log(count({ value: 1, children: [{ value: 2, children: [] }] }));Progettare rispettando i limiti
Preferisca dati superficiali, pattern ricorsivi in coda con accumulatori e limiti espliciti della profondità. Con queste abitudini, raramente raggiungerà il limite nel codice reale.
type Length<T extends unknown[]> = T["length"];
type N = Length<[1, 2, 3]>; // 3
const n: N = 3;
console.log(n);Verifica rapida: limiti della ricorsione
Verifichi la Sua comprensione della profondità e dei limiti della ricorsione.
Riepilogo: profondità e limiti della ricorsione
Ha imparato che TypeScript limita la profondità della ricorsione a livello di tipo, che i pattern ricorsivi in coda con accumulatori e limiti espliciti della profondità sono utili e che i dati ricorsivi di uso quotidiano raramente raggiungono il limite.
type Reverse<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R] ? Reverse<R, [H, ...Acc]> : Acc;
const r: Reverse<[1, 2]> = [2, 1];
console.log(r);Domande Frequenti
La lezione «Profondità e limiti della ricorsione» è gratuita?
Sì — il testo completo di «Profondità e limiti della ricorsione» è 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 «Profondità e limiti della ricorsione»?
Comprenda i vincoli di TypeScript sulla profondità della ricorsione. 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 4 di 4.
Quanto tempo richiede la lezione «Profondità e limiti della ricorsione»?
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
- Definizioni di tipi ricorsivi
- Tipizzare le strutture ad albero
- Tipi per i valori JSON
- Profondità e limiti della ricorsione