TypeScript Academy · leksjon

En liten rutestiparser på typenivå

Parser rutestier til typesatte parameterobjekter.

Leksjon 4 av 413 trinn

En liten rutestiparser på typenivå er en gratis leksjon i TypeScript Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i TypeScript Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i TypeScript Academy inneholder totalt 4 leksjoner.

Målet

Det bygges en ruteparser som leser en sti som "users/:id/posts/:postId" og produserer et typebestemt params-objekt { id: string; postId: string }, utelukkende ved kompilering. Dette er et reelt mønster som brukes av typebestemte rutere.

type Params = ParseRoute<"users/:id/posts/:postId">;
// Goal: { id: string; postId: string }

Gjenkjenne en parameter

Et banesegment er en parameter når det starter med ":". Dette prefikset matches med en template literal, og parameternavnet etter kolon infereres.

Notasjon: I ekte TypeScript skrives template literal-typer med backtick-avgrensede strenger som inneholder plassholdere med dollar og krøllparenteser. I disse kodeutdragene vises dette mønsteret som Tpl<...>, der hver del listes i rekkefølge; et backtick-mønster som samsvarer med det bokstavelige prefikset etterfulgt av Rest, vises for eksempel som Tpl<'prefix', infer Rest>.

type ParamName<S> = S extends Tpl<':', infer Name> ? Name : never;
// Tpl<...> denotes a backtick template literal type: a colon then Name

type X = ParamName<':id'>;   // 'id'
type Y = ParamName<'users'>; // never

Oppdeling av stien

Del først ruten opp i segmenter ved hjelp av "/", og bruk typen Split på nytt. Hvert segment er deretter enten en literal eller en parameter.

type Split<S extends string, Sep extends string> =
  S extends Tpl<infer H, Sep, infer T> ? [H, ...Split<T, Sep>] : [S];
// Tpl<H, Sep, T> = a template literal type matching H, then Sep, then T

type Segs = Split<'users/:id', '/'>; // ['users', ':id']

Direkte rekursjon med maler

Det er også mulig å parse råstrengen uten å dele den opp først, ved å matche ett segment om gangen. Match frem til neste "/", håndter segmentet, og rekursér deretter på resten.

type ParseRoute<S extends string> =
  S extends Tpl<infer Seg, '/', infer Rest>
    ? SegParam<Seg> & ParseRoute<Rest>
    : SegParam<S>;
// Tpl<Seg, '/', Rest> matches a segment, a slash, then the rest

Parameter per segment

Hjelpefunksjonen gjør et enkelt segment om til enten et objekt med én egenskap, hvis det er en parameter, eller et tomt objekt, hvis det er en literal.

type SegParam<S extends string> =
  S extends Tpl<':', infer Name> ? { [K in Name]: string } : {};
// Tpl<':', Name> matches a colon followed by the param name

type X = SegParam<':id'>;   // { id: string }
type Y = SegParam<'posts'>; // {}

Kombinere med intersection

Hvert segment bidrar med parametrene sine via en interseksjon. Tomme objekter forsvinner i en interseksjon, så bare faktiske parametere blir igjen i den endelige typen.

type Params = ParseRoute<"users/:id/posts/:postId">;
// { id: string } & {} & { postId: string } & {}
// = { id: string; postId: string }

Følge parsingen

For "users/:id/posts/:postId":

  • Seg "users" -> {} , rekursjon på ":id/posts/:postId"
  • Seg ":id" -> { id: string }, rekursjon på "posts/:postId"
  • Seg "posts" -> {}, rekursjon på ":postId"
  • Seg ":postId" -> { postId: string }, basistilfelle
type Final = { id: string } & { postId: string };

Rydde opp i resultatet

Interseksjonen av objekter vises på en uhåndterlig måte. En "prettify"-hjelpefunksjon flater den ut til én ryddig objekttype ved hjelp av en mapped type over nøklene.

type Prettify<T> = { [K in keyof T]: T[K] } & {};

type Clean = Prettify<ParseRoute<"users/:id">>; // { id: string }

Bruke parseren

Koble den parsede typen til en funksjon, slik at handleren mottar riktig typede parametre. En feil nøkkel blir en kompileringsfeil.

declare function route<P extends string>(
  path: P,
  handler: (params: Prettify<ParseRoute<P>>) => void
): void;

route("users/:id", p => { const id: string = p.id; });

Fordelen med typebestemte parametre

Kompilatoren utleder nå params direkte fra selve rutestrengen. Hvis en parameter får nytt navn i stien, oppdateres alle handlere automatisk med de forventede nøklene. Ingen manuell grensesnittdefinisjon og ingen uoverensstemmelse mellom rute og handler.

route("users/:userId", p => {
  const u = p.userId; // ok
  // const x = p.id; // error: id does not exist
});

Utvide parseren

Denne lille parseren er utgangspunktet for en fullstendig typebestemt ruter. Det kan legges til typebestemte verdier (tallparametre), jokertegn og valgfrie segmenter, alt ved å berike hjelpefunksjonen per segment med flere template-mønstre. Strukturen med rekursive maler forblir den samme.

type SegParam2<S extends string> =
  S extends Tpl<':', infer N, '(number)'> ? { [K in N]: number }
  : S extends Tpl<':', infer N> ? { [K in N]: string }
  : {};
// Tpl<...> stands for a backtick template literal type pattern

Hurtigsjekk

Test forståelsen av ruteparseren.

Oppsummering

Det er bygget en ruteparser som fungerer ved kompilering.

  • Match hvert segment med rekursiv inferering av template literals.
  • Parametersegmenter (:name) blir til { name: string }.
  • Literalsegmenter blir til {} og forsvinner i interseksjonen.
  • Prettify flater ut resultatet til ryddige parametre.

Neste: Kurs 25 med ende-til-ende-typesikkerhet ved hjelp av tRPC.

Gratis å komme i gang

Lær deg TypeScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
101
Leksjoner
352

Ofte stilte spørsmål

Er leksjonen «En liten rutestiparser på typenivå» gratis?

Ja – hele teksten i «En liten rutestiparser på typenivå» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av TypeScript Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i TypeScript Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «En liten rutestiparser på typenivå»?

Parser rutestier til typesatte parameterobjekter. Du øver på TypeScript Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med TypeScript Academy?

Ingen tidligere erfaring er nødvendig. TypeScript Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «En liten rutestiparser på typenivå»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne TypeScript Academy-leksjonen?

Ja. Alle TypeScript Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Grunnleggende parserkombinatorer
  2. Strengsplitting på typenivå
  3. Parsing med template literals
  4. En liten rutestiparser på typenivå
← Tilbake til TypeScript Academy