0Pricing
TypeScript Academy · Leçon

Profondeur et limites de la récursivité

Comprendre les limites de profondeur de récursivité de TypeScript.

Profondeur et limites de la récursivité est une leçon TypeScript Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage TypeScript Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours TypeScript Academy comprend 4 leçons au total.

TypeScript a des limites de récursion

Les types récursifs sont puissants, mais le vérificateur de types limite la profondeur à laquelle il les instancie. Si vous atteignez cette limite, vous obtenez une erreur de profondeur.

// Excessively deep recursive types can produce:
// "Type instantiation is excessively deep and possibly infinite."

Origine des erreurs de profondeur

Les types conditionnels qui récursent sans cas de base clair et décroissant peuvent s’emballer, surtout lorsqu’ils sont combinés à de grandes unions ou à la construction de tuples.

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

Une récursion bornée sûre

Gardez la récursion peu profonde et bornée. Construire un petit tuple ne pose pas de problème ; le cas de base Acc["length"] extends N l’arrête rapidement.

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);

Modèles de types récursifs terminaux

TypeScript optimise certains types conditionnels récursifs terminaux en transportant un accumulateur, ce qui permet une récursion plus profonde qu’avec un imbrication naïve.

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);

Pourquoi les accumulateurs sont utiles

Transmettre les résultats dans un accumulateur maintient la récursion en position terminale, ce que TypeScript peut dérouler plus efficacement que des conditions profondément imbriquées.

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);

Éviter la récursion non terminale

Envelopper l’appel récursif dans une autre opération de type rompt la position terminale et peut provoquer l’atteinte des limites plus tôt. Préférez plutôt transporter l’état dans un accumulateur.

// 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");

Plafonner explicitement la profondeur

Ajoutez un compteur de profondeur afin que le type s’arrête après un nombre fixe de niveaux, en échangeant l’exhaustivité contre une terminaison garantie.

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 profondeur pratique convient généralement

Les types récursifs courants, les listes chaînées, les arbres et JSON n’atteignent jamais la limite, car les données que vous instanciez sont peu profondes. Les limites concernent principalement les calculs lourds au niveau des types.

type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const v: Json = { a: { b: { c: 1 } } }; // fine, shallow
console.log(v);

Reconnaître le message d’erreur

Lorsque vous voyez « excessivement profond et potentiellement infini », recherchez un cas de base manquant, un accumulateur en position non terminale ou une entrée trop volumineuse.

// 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 récursion à l’exécution est distincte

Ces limites concernent la récursion au niveau des types. Les fonctions récursives ordinaires qui utilisent des types récursifs s’exécutent à l’exécution et sont limitées uniquement par la pile d’appels.

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: [] }] }));

Concevoir dans les limites

Privilégiez des données peu profondes, des modèles récursifs terminaux avec accumulateurs et des plafonds de profondeur explicites. Avec ces habitudes, vous atteindrez rarement la limite dans du code réel.

type Length<T extends unknown[]> = T["length"];
type N = Length<[1, 2, 3]>; // 3
const n: N = 3;
console.log(n);

Vérification rapide : limites de récursion

Vérifiez votre compréhension de la profondeur et des limites de récursion.

Récapitulatif : profondeur et limites de récursion

Vous avez appris que TypeScript plafonne la profondeur de récursion au niveau des types, que les modèles récursifs terminaux avec accumulateurs et les plafonds de profondeur explicites sont utiles, et que les données récursives courantes atteignent rarement la 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);

Questions Fréquemment Posées

La leçon « Profondeur et limites de la récursivité » est-elle gratuite ?

Oui — le texte complet de « Profondeur et limites de la récursivité » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours TypeScript Academy, passe à CoddyKit PRO. Le cours TypeScript Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Profondeur et limites de la récursivité » ?

Comprendre les limites de profondeur de récursivité de TypeScript. Tu pratiques TypeScript Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer TypeScript Academy ?

Aucune expérience préalable n'est requise. TypeScript Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Profondeur et limites de la récursivité » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon TypeScript Academy ?

Oui. Chaque leçon TypeScript Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Définitions de types récursifs
  2. Typer des structures arborescentes
  3. Types de valeurs JSON
  4. Profondeur et limites de la récursivité
← Retour à TypeScript Academy