Slovenščina

Odkrijte TypeScript diskriminirane unije, močno orodje za gradnjo robustnih in tipsko varnih stanj. Naučite se definirati stanja, obravnavati prehode in izkoristiti TypeScriptov tipski sistem.

TypeScript Diskriminirane Unije: Gradnja Tipsko Varnih Strojnih Stanj

Na področju razvoja programske opreme je učinkovito upravljanje stanja aplikacije ključnega pomena. Strojna stanja ponujajo močno abstrakcijo za modeliranje kompleksnih stanjskih sistemov, zagotavljajo predvidljivo obnašanje in poenostavljajo sklepanje o logiki sistema. TypeScript s svojim robustnim tipskim sistemom ponuja fantastičen mehanizem za gradnjo tipsko varnih stanj z uporabo diskriminiranih unij (znanih tudi kot označene unije ali algebrski podatkovni tipi).

Kaj so Diskriminirane Unije?

Diskriminirana unija je tip, ki predstavlja vrednost, ki je lahko ena izmed več različnih tipov. Vsak od teh tipov, znanih kot člani unije, si deli skupno, ločeno lastnost, imenovano diskriminant ali oznaka. Ta diskriminant omogoča TypeScriptu natančno določiti, kateri član unije je trenutno aktiven, kar omogoča močno tipsko preverjanje in samodejno dopolnjevanje.

Pomislite na semafor. Lahko je v enem izmed treh stanj: Rdeče, Rumeno ali Zeleno. Lastnost 'barva' deluje kot diskriminant in nam natančno pove, v kakšnem stanju je luč.

Zakaj uporabiti Diskriminirane Unije za Strojna Stanja?

Diskriminirane unije prinašajo več ključnih prednosti pri gradnji stanj v TypeScriptu:

Definiranje Stroja Stanj z Diskriminiranimi Unijami

Ponazorimo, kako definirati stroj stanj z uporabo diskriminiranih unij s praktičnim primerom: sistem obdelave naročil. Naročilo je lahko v naslednjih stanjih: Čakajoče, V Obdelavi, Odposlano in Dostavljeno.

1. Korak: Definirajte Tipe Stanja

Najprej definiramo posamezne tipe za vsako stanje. Vsak tip bo imel lastnost `type`, ki deluje kot diskriminant, skupaj z vsemi podatki, specifičnimi za stanje.


interface Pending {
  type: "pending";
  orderId: string;
  customerName: string;
  items: string[];
}

interface Processing {
  type: "processing";
  orderId: string;
  assignedAgent: string;
}

interface Shipped {
  type: "shipped";
  orderId: string;
  trackingNumber: string;
}

interface Delivered {
  type: "delivered";
  orderId: string;
  deliveryDate: Date;
}

2. Korak: Ustvarite Tip Diskriminirane Unije

Nato ustvarimo diskriminirano unijo s kombiniranjem teh posameznih tipov z uporabo operatorja `|` (unija).


type OrderState = Pending | Processing | Shipped | Delivered;

Zdaj `OrderState` predstavlja vrednost, ki je lahko bodisi `Pending`, `Processing`, `Shipped` ali `Delivered`. Lastnost `type` v vsakem stanju deluje kot diskriminant, kar omogoča TypeScriptu, da jih razlikuje.

Obravnavanje Prehodov Stanja

Zdaj, ko smo definirali naš stroj stanj, potrebujemo mehanizem za prehode med stanji. Ustvarimo funkcijo `processOrder`, ki kot vhod sprejme trenutno stanje in dejanje ter vrne novo stanje.


interface Action {
  type: string;
  payload?: any;
}

function processOrder(state: OrderState, action: Action): OrderState {
  switch (state.type) {
    case "pending":
      if (action.type === "startProcessing") {
        return {
          type: "processing",
          orderId: state.orderId,
          assignedAgent: action.payload.agentId,
        };
      }
      return state; // Brez spremembe stanja

    case "processing":
      if (action.type === "shipOrder") {
        return {
          type: "shipped",
          orderId: state.orderId,
          trackingNumber: action.payload.trackingNumber,
        };
      }
      return state; // Brez spremembe stanja

    case "shipped":
      if (action.type === "deliverOrder") {
        return {
          type: "delivered",
          orderId: state.orderId,
          deliveryDate: new Date(),
        };
      }
      return state; // Brez spremembe stanja

    case "delivered":
      // Naročilo je že dostavljeno, nadaljnjih dejanj ni
      return state;

    default:
      // To se zaradi preverjanja izčrpnosti nikoli ne bi smelo zgoditi
      return state; // Ali pa vrže izjemo
  }
}

Razlaga

Izkoristite Preverjanje Izčrpnosti

Preverjanje izčrpnosti TypeScripta je zmogljiva funkcija, ki zagotavlja, da obravnavate vsa možna stanja v vašem stroju stanj. Če dodate novo stanje v unijo `OrderState`, a pozabite posodobiti funkcije `processOrder`, vam bo TypeScript sporočil napako.

Za omogočanje preverjanja izčrpnosti lahko uporabite tip `never`. Znotraj privzetega `case` vaše preklopne izjave dodelite stanje spremenljivki tipa `never`.


function processOrder(state: OrderState, action: Action): OrderState {
  switch (state.type) {
    // ... (prejšnji primeri) ...

    default:
      const _exhaustiveCheck: never = state;
      return _exhaustiveCheck; // Ali pa vrže izjemo
  }
}

Če preklopna izjava obravnava vse možne vrednosti `OrderState`, bo spremenljivka `_exhaustiveCheck` tipa `never` in koda se bo kompilala. Vendar, če dodate novo stanje v unijo `OrderState` in ga pozabite obravnavati v preklopni izjavi, bo spremenljivka `_exhaustiveCheck` drugačnega tipa in TypeScript bo vrgel napako med kompilacijo, s čimer vas opozori na manjkajoči primer.

Praktični Primere in Aplikacije

Diskriminirane unije so uporabne v širokem spektru scenarijev, ki presegajo preprosto obdelavo naročil:

Primer: Upravljanje Stanja UI

Oglejmo si preprost primer upravljanja stanja UI komponente, ki pridobiva podatke iz API-ja. Lahko definiramo naslednja stanja:


interface Initial {
  type: "initial";
}

interface Loading {
  type: "loading";
}

interface Success {
  type: "success";
  data: T;
}

interface Error {
  type: "error";
  message: string;
}

type UIState = Initial | Loading | Success | Error;

function renderUI(state: UIState): React.ReactNode {
  switch (state.type) {
    case "initial":
      return 

Kliknite gumb za nalaganje podatkov.

; case "loading": return

Nalaganje...

; case "success": return
{JSON.stringify(state.data, null, 2)}
; case "error": return

Napaka: {state.message}

; default: const _exhaustiveCheck: never = state; return _exhaustiveCheck; } }

Ta primer prikazuje, kako se lahko diskriminirane unije uporabljajo za učinkovito upravljanje različnih stanj UI komponente, kar zagotavlja, da se UI pravilno prikaže glede na trenutno stanje. Funkcija `renderUI` obravnava vsako stanje ustrezno, kar zagotavlja jasen in tipsko varen način upravljanja UI.

Najboljše Prakse za Uporabo Diskriminiranih Unij

Za učinkovito uporabo diskriminiranih unij v vaših projektih TypeScript, upoštevajte naslednje najboljše prakse:

Napredne Tehnike

Pogojni Tipi

Pogojne tipe je mogoče kombinirati z diskriminiranimi unijami, da ustvarite še bolj zmogljiva in prilagodljiva stanja. Na primer, pogojne tipe lahko uporabite za definiranje različnih povratnih tipov funkcije glede na trenutno stanje.


function getData(state: UIState): T | undefined {
  if (state.type === "success") {
    return state.data;
  }
  return undefined;
}

Ta funkcija uporablja preprosto `if` izjavo, vendar bi jo bilo mogoče narediti bolj robustno z uporabo pogojnih tipov, da bi zagotovili, da je določen tip vedno vrnjen.

Pomožni Tipi

Pomožni tipi TypeScripta, kot sta `Extract` in `Omit`, so lahko koristni pri delu z diskriminiranimi unijami. `Extract` vam omogoča, da izluščite določene člane iz tipa unije na podlagi pogoja, medtem ko `Omit` vam omogoča, da odstranite lastnosti iz tipa.


// Izlušči stanje "success" iz unije UIState
type SuccessState = Extract, { type: "success" }>;

// Odsrani lastnost 'message' iz vmesnika Error
type ErrorWithoutMessage = Omit;

Primeri iz Resničnega Življenja iz Različnih Panog

Moč diskriminiranih unij se razteza preko različnih panog in domen aplikacij:

Zaključek

TypeScript diskriminirane unije zagotavljajo močan in tipsko varen način gradnje strojev stanj. Z jasnim definiranjem možnih stanj in prehodov lahko ustvarite bolj robustno, vzdrževano in razumljivo kodo. Kombinacija tipne varnosti, preverjanja izčrpnosti in izboljšanega samodejnega dopolnjevanja naredi diskriminirane unije neprecenljivo orodje za vsakega razvijalca TypeScripta, ki se ukvarja s kompleksnim upravljanjem stanj. Sprejmite diskriminirane unije v svojem naslednjem projektu in izkusite prednosti tipsko varnega upravljanja stanj iz prve roke. Kot smo prikazali z raznolikimi primeri od e-trgovine do zdravstva ter logistike do izobraževanja, je načelo tipsko varnega upravljanja stanj preko diskriminiranih unij univerzalno uporabno.

Ne glede na to, ali gradite preprosto UI komponento ali kompleksno podjetniško aplikacijo, vam lahko diskriminirane unije pomagajo učinkoviteje upravljati stanje in zmanjšati tveganje napak med izvajanjem. Torej, potopite se in raziščite svet tipsko varnih strojev stanj s TypeScriptom!