TypeScript Academy · Oppitunti

Rekursion syvyys ja rajoitukset

Ymmärtäkää TypeScriptin rekursion syvyyttä koskevat rajoitukset.

Oppitunti 4/413 vaihetta

Rekursion syvyys ja rajoitukset on ilmainen TypeScript Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu TypeScript Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. TypeScript Academy-kurssilla on yhteensä 4 oppituntia.

TypeScriptin rekursiorajat

Rekursiiviset tyypit ovat tehokkaita, mutta tyyppien tarkistin rajoittaa sitä, kuinka syvälle se niitä instansioi. Kun raja saavutetaan, saatte syvyysvirheen.

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

Mistä syvyysvirheet johtuvat

Ehdolliset tyypit, jotka rekursioivat ilman selkeää ja pienenevää perustapausta, voivat lähteä kiertämään loputtomasti, erityisesti yhdistettyinä suuriin unioneihin tai tuplien rakentamiseen.

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

Turvallinen rajattu rekursio

Pidättehkää rekursio matalana ja rajattuna. Pienen tuplen rakentaminen on turvallista; perustapaus Acc["length"] extends N pysäyttää sen nopeasti.

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

Häntärekursiiviset tyyppimallit

TypeScript optimoi tietyt häntärekursiiviset ehdolliset tyypit kuljettamalla akkumulaattoria, mikä mahdollistaa syvemmän rekursion kuin naiivi sisäkkäisyys.

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

Miksi akkumulaattorit auttavat

Tulosten välittäminen akkumulaattorissa pitää rekursion häntäasemassa, jonka TypeScript voi avata tehokkaammin kuin syvälle sisäkkäiset ehdot.

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

Muun kuin häntärekursion välttäminen

Rekursiivisen kutsun kääriminen toisen tyyppioperaation sisään rikkoo häntäaseman ja voi saavuttaa rajat aiemmin. Kuljettakaa tila sen sijaan akkumulaattorissa.

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

Syvyyden rajaaminen eksplisiittisesti

Lisätkää syvyyslaskuri, jotta tyyppi lopettaa tietyn tasomäärän jälkeen. Näin täydellisyydestä tingitään varman päättymisen takaamiseksi.

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

Käytännön syvyys riittää yleensä

Tavalliset rekursiiviset tyypit, kuten linkitetyt listat, puut ja JSON, eivät yleensä saavuta rajaa, koska instansioitava data on matalaa. Rajat vaikuttavat pääasiassa raskaaseen tyyppitason laskentaan.

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

Virheilmoituksen tunnistaminen

Kun näette viestin "excessively deep and possibly infinite", etsikää puuttuvaa perustapausta, ei-häntäasemassa olevaa akkumulaattoria tai liian suurta syötettä.

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

Ajonaikainen rekursio on erillinen asia

Nämä rajat koskevat tyyppitason rekursiota. Tavalliset rekursiiviset funktiot rekursiivisilla tyypeillä suoritetaan ajonaikaisesti, ja niitä rajoittaa vain kutsupino.

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

Suunnittelu rajojen puitteissa

Suosikaa matalaa dataa, akkumulaattoreita käyttäviä häntärekursiivisia malleja ja eksplisiittisiä syvyysrajoja. Näillä tavoilla rajaa tarvitsee harvoin kohdata todellisessa koodissa.

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

Pikatarkistus: rekursiorajat

Testatkaa, miten hyvin ymmärrätte rekursion syvyyden ja rajat.

Kertaus: rekursion syvyys ja rajat

Opitte, että TypeScript rajoittaa tyyppitason rekursion syvyyttä, että akkumulaattoreita käyttävät häntärekursiiviset mallit ja eksplisiittiset syvyysrajat auttavat ja että tavallinen rekursiivinen data saavuttaa rajan harvoin.

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

Opi TypeScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
101
Oppitunnit
352

Usein kysytyt kysymykset

Onko oppitunti ”Rekursion syvyys ja rajoitukset” ilmainen?

Kyllä – oppitunnin ”Rekursion syvyys ja rajoitukset” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko TypeScript Academy-kurssin, päivitä CoddyKit PROhon. TypeScript Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Rekursion syvyys ja rajoitukset”?

Ymmärtäkää TypeScriptin rekursion syvyyttä koskevat rajoitukset. Harjoittelet TypeScript Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni TypeScript Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin TypeScript Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Rekursion syvyys ja rajoitukset”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä TypeScript Academy-oppitunnilla?

Kyllä. Jokainen TypeScript Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Rekursiivisten tyyppimäärittelyjen perusteet
  2. Puurakenteiden tyypitys
  3. JSON-arvotyypit
  4. Rekursion syvyys ja rajoitukset
← Takaisin: TypeScript Academy