TypeScript Academy · leksjon

Innsnevring på diskriminatoren

La TypeScript snevre inn varianter i switch-setninger.

Leksjon 2 av 413 trinn

Innsnevring på diskriminatoren er en gratis leksjon i TypeScript Academy på CoddyKit. Dette er leksjon 2 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.

Innsnevring basert på diskriminanten

Når diskriminanten er kontrollert, innsnevrer TypeScript unionen til det samsvarende medlemmet og gir tilgang til de spesifikke feltene. Det er dette som gjør mønsteret nyttig.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape) {
  if (s.kind === "circle") return Math.PI * s.radius ** 2;
  return s.side ** 2;
}
console.log(area({ kind: "circle", radius: 2 }).toFixed(2));

Bruke switch på diskriminanten

En switch over diskriminanten er den ryddigste måten å håndtere hver variant på. Inne i hver case blir typen automatisk innsnevret.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.radius ** 2;
    case "square": return s.side ** 2;
  }
}
console.log(area({ kind: "square", side: 5 }));

Medlemsspesifikke felt i hver case

I "circle"-casen er s.radius tilgjengelig, men s.side er det ikke. TypeScript vet nøyaktig hvilket medlem som behandles.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function describe(s: Shape) {
  switch (s.kind) {
    case "circle": return "r=" + s.radius;
    case "square": return "side=" + s.side;
  }
}
console.log(describe({ kind: "circle", radius: 9 }));

Innsnevring basert på if

Det er ikke nødvendig å bruke switch. En enkel if som sammenligner diskriminanten, innsnevrer typen like effektivt.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function perimeter(s: Shape): number {
  if (s.kind === "circle") {
    return 2 * Math.PI * s.radius;
  }
  return 4 * s.side;
}
console.log(perimeter({ kind: "square", side: 3 }));

Tilgang til feil felt mislykkes

Før innsnevringen kan De ikke bruke et felt som er spesifikt for ett medlem. TypeScript rapporterer en feil fordi egenskapen ikke finnes på alle medlemmer.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function broken(s: Shape) {
  // Error: radius does not exist on Square
  // return s.radius;
  return s.kind;
}
console.log(broken({ kind: "square", side: 1 }));

Innsnevring med boolske diskriminanter

For en { ok: true } | { ok: false }-union innsnevrer kontrollen if (r.ok) typen til suksessmedlemmet.

type Result =
  | { ok: true; data: string }
  | { ok: false; error: string };

function handle(r: Result): string {
  if (r.ok) return "Data: " + r.data;
  return "Error: " + r.error;
}
console.log(handle({ ok: false, error: "boom" }));

Innsnevring med tidlig retur

En tidlig retur for én variant innsnevrer resten av koden til de andre variantene. Det er en ryddig måte å behandle én case om gangen på.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function label(s: Shape): string {
  if (s.kind === "circle") return "circle";
  // s is now narrowed to Square here
  return "square with side " + s.side;
}
console.log(label({ kind: "square", side: 8 }));

Kombinere med andre betingelser

Diskriminantkontrollen kan kombineres med annen logikk. TypeScript beholder innsnevringen så lenge diskriminantbetingelsen er sann i denne grenen.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function bigCircle(s: Shape): boolean {
  return s.kind === "circle" && s.radius > 100;
}
console.log(bigCircle({ kind: "circle", radius: 150 }));

Innsnevring i array-filtre

Innsnevring fungerer også inne i callback-funksjoner. Her kontrolleres hver form individuelt mens arrayet itereres.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const shapes: Shape[] = [
  { kind: "circle", radius: 1 },
  { kind: "square", side: 2 }
];
shapes.forEach(s => {
  if (s.kind === "circle") console.log("c", s.radius);
  else console.log("s", s.side);
});

Returverdier fra switch forblir typesikre

Når en switch håndterer alle casene og returnerer, utleder TypeScript en presis returtype fra unionen av resultatene fra alle casene.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function tag(s: Shape) {
  switch (s.kind) {
    case "circle": return s.radius;
    case "square": return s.side;
  }
}
console.log(tag({ kind: "circle", radius: 4 }));

Sette sammen innsnevringen

Enten De bruker switch eller if, er det kontrollen av diskriminanten som gjør medlemmenes felt trygt tilgjengelige. Deretter skal vi garantere at alle caser håndteres.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape): number {
  return s.kind === "circle" ? Math.PI * s.radius ** 2 : s.side ** 2;
}
console.log(Math.round(area({ kind: "circle", radius: 10 })));

Kort kontroll: innsnevring

Test forståelsen av innsnevring basert på diskriminanten.

Oppsummering: innsnevring basert på diskriminanten

De har sett at kontroll av diskriminanten med switch eller if innsnevrer unionen til ett medlem og bare eksponerer feltene til dette medlemmet. Tidlige returer og kombinerte betingelser bevarer innsnevringen.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const s: Shape = { kind: "square", side: 7 };
console.log(s.kind === "square" ? s.side : 0);
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 «Innsnevring på diskriminatoren» gratis?

Ja – hele teksten i «Innsnevring på diskriminatoren» 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 «Innsnevring på diskriminatoren»?

La TypeScript snevre inn varianter i switch-setninger. 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 2 av 4.

Hvor lang tid tar leksjonen «Innsnevring på diskriminatoren»?

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. Bygge diskriminerte unioner
  2. Innsnevring på diskriminatoren
  3. Kontroll av fullstendighet med never
  4. Modellere tilstandsmaskiner
← Tilbake til TypeScript Academy