Rekursion på typeniveau
Gentag over typer ved hjælp af rekursive betingede typer
Rekursion på typeniveau er en gratis TypeScript Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i TypeScript Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. TypeScript Academy-kurset indeholder 4 lektioner i alt.
Rekursion i typer
En betinget type må referere til sig selv. Det giver typesproget løkker. Det meste rekursion på typeniveau gennemgår en tupel ét element ad gangen, fjerner hovedet og kalder sig selv på halen.
type Length<T extends unknown[]> =
T extends [unknown, ...infer Rest]
? Length<Rest>
: 0;
// (this counts down to a base case)Basistilfældet
Al rekursion har brug for en stoppelsebetingelse. For tupler er det normalt den tomme tupel. Når mønsteret [head, ...rest] ikke længere matcher, er du nået til slutningen, og du returnerer et fast resultat.
type IsEmpty<T extends unknown[]> =
T extends [] ? true : false;
type A = IsEmpty<[]>; // true
type B = IsEmpty<[1, 2]>; // falseHoved og hale
Det centrale trin er at opdele en tupel i dens første element og den resterende tupel ved at bruge infer sammen med spredningsmønsteret.
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]Behandling element for element
Kombinér hoved, hale og rekursion for at transformere en hel tupel. ToStrings genopbygger tupellen og erstatter hver elementtype med string.
type ToStrings<T extends unknown[]> =
T extends [infer H, ...infer R]
? [string, ...ToStrings<R>]
: [];
type A = ToStrings<[1, true, 3]>; // [string, string, string]Akkumulatormønsteret
Ofte opbygger du et resultat i en ekstra parameter, der kaldes en akkumulator. Den starter tom og vokser for hvert trin. Det undgår, at strukturen gennemgås igen, og det er standardteknikken til løkker på typeniveau.
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]Gennemgang af akkumulatoren
Følg Reverse<[1,2,3]>:
- Trin 1: H=1, Acc bliver til [1]
- Trin 2: H=2, Acc bliver til [2,1]
- Trin 3: H=3, Acc bliver til [3,2,1]
- Tupellen er tom, returnér Acc = [3,2,1]
Akkumulatoren fører resultatet med ned gennem hvert rekursivt kald.
type R = Reverse<["a", "b"]>; // ["b", "a"]Rekursion over unioner
Du kan også bruge rekursion til at samle en union af strenge. Her sammenkæder vi tupelens elementer til én strengliteraltype med et skilletegn imellem.
Notation: I rigtig TypeScript skrives skabelonliteraltyper med strenge afgrænset af backtick-tegn, som indeholder dollar-krølleparentespladsholdere. I disse kodestykker viser vi mønsteret som Tpl<...>, hvor hver del angives i rækkefølge; f.eks. vises en backtick-skabelon, der matcher det bogstavelige præfiks efterfulgt af Rest, som 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'Tælling med rekursion
Rekursion kombineret med en akkumulator kan tælle. Opbyg en tupel af unknown med samme længde som inddataene, og aflæs derefter dens length. Du kommer til at bruge dette meget i aritmetikkurset.
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"]>; // 3Filtrering med rekursion
Gå en tupel igennem, og behold kun de elementer, der opfylder en betingelse, mens du fjerner resten. Spring et element over ved ikke at føje det til akkumulatoren.
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"]Grænser for rekursionsdybden
Compileren begrænser rekursionsdybden (historisk omkring 50, mens optimeringer af halerekursion i nogle mønstre tillader flere). For meget store tupler kan du ramme fejlen Typeinstansieringen er for dyb. Brug akkumulatorformen (haleformen) for at skubbe grænsen højere.
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]Samlet overblik
Opdeling i hoved og hale, et basistilfælde og en akkumulator er de tre ingredienser i næsten alle løkker på typeniveau. Med dem kan du afbilde, filtrere, vende, tælle og sammenføje tupler udelukkende i typesystemet.
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]]Hurtig kontrol
Afprøv din forståelse af akkumulatormønsteret.
Opsummering
Nu kan du skrive løkker på typeniveau.
- Selvrefererende betingelser skaber rekursion.
- Opdel tupler i
[H, ...R], og rekursér over halen. - Et basistilfælde (en tom tupel) stopper løkken.
- En akkumulator opbygger resultatet og muliggør dyb rekursion.
Dernæst: hvordan betingelser opfører sig særligt over unioner.
Lær TypeScript med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 101
- Lektioner
- 352
Ofte stillede spørgsmål
Er lektionen “Rekursion på typeniveau” gratis?
Ja — hele teksten til “Rekursion på typeniveau” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af TypeScript Academy-kurset, skal du opgradere til CoddyKit PRO. TypeScript Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Rekursion på typeniveau”?
Gentag over typer ved hjælp af rekursive betingede typer Du øver dig i TypeScript Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på TypeScript Academy?
Der kræves ingen tidligere erfaring. TypeScript Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Rekursion på typeniveau”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne TypeScript Academy-lektion?
Ja. Alle TypeScript Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Typer som beregningssprog
- Betingelser på typeniveau
- Rekursion på typeniveau
- Distributive betingede typer