Latviešu

Izpētiet TypeScript diskriminētās apvienības — spēcīgu rīku robustu un tipdrošu stāvokļu mašīnu izveidei. Uzziniet, kā definēt stāvokļus, apstrādāt pārejas un izmantot TypeScript tipu sistēmu, lai palielinātu koda uzticamību.

TypeScript Diskriminētās Apvienības: Tipdrošas Stāvokļu Mašīnas Izveide

Programmatūras izstrādes jomā lietojumprogrammu stāvokļa efektīva pārvaldība ir ļoti svarīga. Stāvokļu mašīnas nodrošina spēcīgu abstrakciju sarežģītu, stāvoklīgu sistēmu modelēšanai, nodrošinot paredzamu uzvedību un vienkāršojot spriešanu par sistēmas loģiku. TypeScript ar savu robusto tipu sistēmu piedāvā fantastisku mehānismu tipdrošu stāvokļu mašīnu izveidei, izmantojot diskriminētās apvienības (pazīstamas arī kā iezīmētas apvienības vai algebriskie datu tipi).

Kas ir Diskriminētās Apvienības?

Diskriminētā apvienība ir tips, kas attēlo vērtību, kas var būt viens no vairākiem dažādiem tipiem. Katram no šiem tipiem, kas pazīstami kā apvienības dalībnieki, ir kopīga, atšķirīga īpašība, ko sauc par diskriminantu vai tagu. Šis diskriminants ļauj TypeScript precīzi noteikt, kurš apvienības dalībnieks pašlaik ir aktīvs, nodrošinot spēcīgu tipu pārbaudi un automātisko pabeigšanu.

Padomājiet par to kā par luksoforu. Tas var būt vienā no trim stāvokļiem: sarkans, dzeltens vai zaļš. Īpašība 'color' darbojas kā diskriminants, precīzi norādot, kādā stāvoklī ir gaisma.

Kāpēc Izmantot Diskriminētās Apvienības Stāvokļu Mašīnām?

Diskriminētās apvienības sniedz vairākus galvenos ieguvumus, veidojot stāvokļu mašīnas TypeScript:

Stāvokļu Mašīnas Definēšana ar Diskriminētām Apvienībām

Ilustrēsim, kā definēt stāvokļu mašīnu, izmantojot diskriminētās apvienības ar praktisku piemēru: pasūtījumu apstrādes sistēmu. Pasūtījums var būt šādos stāvokļos: Gaida, Apstrādā, Nosūtīts un Piegādāts.

1. solis: Definējiet Stāvokļu Tipus

Vispirms mēs definējam atsevišķus tipus katram stāvoklim. Katram tipam būs īpašība `type`, kas darbojas kā diskriminants, kā arī visi stāvoklim specifiski dati.


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. solis: Izveidojiet Diskriminēto Apvienības Tipu

Tālāk mēs izveidojam diskriminēto apvienību, apvienojot šos atsevišķus tipus, izmantojot operatoru `|` (apvienošana).


type OrderState = Pending | Processing | Shipped | Delivered;

Tagad `OrderState` attēlo vērtību, kas var būt vai nu `Pending`, `Processing`, `Shipped` vai `Delivered`. Īpašība `type` katrā stāvoklī darbojas kā diskriminants, ļaujot TypeScript atšķirt tos.

Stāvokļu Pāreju Apstrāde

Tagad, kad esam definējuši savu stāvokļu mašīnu, mums ir nepieciešams mehānisms, lai pārietu starp stāvokļiem. Izveidosim funkciju `processOrder`, kas ņem pašreizējo stāvokli un darbību kā ievadi un atgriež jauno stāvokli.


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; // Bez stāvokļa izmaiņām

    case "processing":
      if (action.type === "shipOrder") {
        return {
          type: "shipped",
          orderId: state.orderId,
          trackingNumber: action.payload.trackingNumber,
        };
      }
      return state; // Bez stāvokļa izmaiņām

    case "shipped":
      if (action.type === "deliverOrder") {
        return {
          type: "delivered",
          orderId: state.orderId,
          deliveryDate: new Date(),
        };
      }
      return state; // Bez stāvokļa izmaiņām

    case "delivered":
      // Pasūtījums jau ir piegādāts, turpmākas darbības nav nepieciešamas
      return state;

    default:
      // Tam nekad nevajadzētu notikt izsmeļošas pārbaudes dēļ
      return state; // Vai mest kļūdu
  }
}

Paskaidrojums

Izsmeļošas Pārbaudes Izmantošana

TypeScript izsmeļošā pārbaude ir spēcīga funkcija, kas nodrošina, ka jūs apstrādājat visus iespējamos stāvokļus savā stāvokļu mašīnā. Ja pievienojat jaunu stāvokli `OrderState` apvienībai, bet aizmirstat atjaunināt funkciju `processOrder`, TypeScript atzīmēs kļūdu.

Lai iespējotu izsmeļošu pārbaudi, varat izmantot tipu `never`. Iekšpus `default` gadījuma jūsu switch priekšrakstā piešķiriet stāvokli mainīgajam ar tipu `never`.


function processOrder(state: OrderState, action: Action): OrderState {
  switch (state.type) {
    // ... (iepriekšējie gadījumi) ...

    default:
      const _exhaustiveCheck: never = state;
      return _exhaustiveCheck; // Vai mest kļūdu
  }
}

Ja `switch` priekšraksts apstrādā visas iespējamās `OrderState` vērtības, mainīgais `_exhaustiveCheck` būs ar tipu `never`, un kods kompilēsies. Tomēr, ja pievienojat jaunu stāvokli `OrderState` apvienībai un aizmirstat to apstrādāt `switch` priekšrakstā, mainīgais `_exhaustiveCheck` būs ar citu tipu, un TypeScript izmetīs kompilēšanas laika kļūdu, brīdinot jūs par trūkstošo gadījumu.

Praktiski Piemēri un Lietojumprogrammas

Diskriminētās apvienības ir piemērojamas plašā diapazonā scenāriju ārpus vienkāršām pasūtījumu apstrādes sistēmām:

Piemērs: UI Stāvokļa Pārvaldība

Apsveriet vienkāršu piemēru par UI komponenta stāvokļa pārvaldību, kas iegūst datus no API. Mēs varam definēt šādus stāvokļus:


interface Initial {
  type: "initial";
}

interface Loading {
  type: "loading";
}

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

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

type UIState<T> = Initial | Loading | Success<T> | Error;

function renderUI<T>(state: UIState<T>): React.ReactNode {
  switch (state.type) {
    case "initial":
      return <p>Noklikšķiniet uz pogas, lai ielādētu datus.</p>;
    case "loading":
      return <p>Ielādē...</p>;
    case "success":
      return <pre>{JSON.stringify(state.data, null, 2)}</pre>;
    case "error":
      return <p>Kļūda: {state.message}</p>;
    default:
      const _exhaustiveCheck: never = state;
      return _exhaustiveCheck;
  }
}

Šis piemērs parāda, kā diskriminētās apvienības var izmantot, lai efektīvi pārvaldītu dažādus UI komponenta stāvokļus, nodrošinot, ka UI tiek atveidots pareizi, pamatojoties uz pašreizējo stāvokli. Funkcija `renderUI` atbilstoši apstrādā katru stāvokli, nodrošinot skaidru un tipdrošu veidu, kā pārvaldīt UI.

Labākā Prakse Diskriminētu Apvienību Izmantošanai

Lai efektīvi izmantotu diskriminētās apvienības savos TypeScript projektos, apsveriet šādu labāko praksi:

Papildu Metodes

Nosacījuma Tipi

Nosacījuma tipus var apvienot ar diskriminētām apvienībām, lai izveidotu vēl spēcīgākas un elastīgākas stāvokļu mašīnas. Piemēram, varat izmantot nosacījuma tipus, lai definētu dažādus atgriešanas tipus funkcijai, pamatojoties uz pašreizējo stāvokli.


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

Šī funkcija izmanto vienkāršu `if` priekšrakstu, bet to varētu padarīt robustāku, izmantojot nosacījuma tipus, lai nodrošinātu, ka vienmēr tiek atgriezts noteikts tips.

Lietderības Tipi

TypeScript lietderības tipi, piemēram, `Extract` un `Omit`, var būt noderīgi, strādājot ar diskriminētām apvienībām. `Extract` ļauj izvilkt konkrētus dalībniekus no apvienības tipa, pamatojoties uz nosacījumu, savukārt `Omit` ļauj noņemt īpašības no tipa.


// Izvelciet "success" stāvokli no UIState apvienības
type SuccessState<T> = Extract<UIState<T>, { type: "success" }>;

// Izlaidiet īpašību 'message' no Error interfeisa
type ErrorWithoutMessage = Omit<Error, "message">;

Reālās Pasaules Piemēri Dažādās Nozarēs

Diskriminētu apvienību spēks sniedzas pāri dažādām nozarēm un lietojumprogrammu domēniem:

Secinājums

TypeScript diskriminētās apvienības nodrošina spēcīgu un tipdrošu veidu, kā veidot stāvokļu mašīnas. Skaidri definējot iespējamos stāvokļus un pārejas, jūs varat izveidot robustāku, uzturamāku un saprotamāku kodu. Tipu drošības, izsmeļošas pārbaudes un uzlabotas koda pabeigšanas kombinācija padara diskriminētās apvienības par nenovērtējamu rīku jebkuram TypeScript izstrādātājam, kas strādā ar sarežģītu stāvokļu pārvaldību. Iekļaujiet diskriminētās apvienības savā nākamajā projektā un izbaudiet tipdrošas stāvokļu pārvaldības priekšrocības no pirmavotiem. Kā mēs esam parādījuši ar dažādiem piemēriem no e-komercijas līdz veselības aprūpei un loģistikas līdz izglītībai, tipdrošas stāvokļu pārvaldības princips, izmantojot diskriminētās apvienības, ir universāli piemērojams.

Neatkarīgi no tā, vai veidojat vienkāršu UI komponentu vai sarežģītu uzņēmuma lietojumprogrammu, diskriminētās apvienības var palīdzēt efektīvāk pārvaldīt stāvokli un samazināt izpildlaika kļūdu risku. Tāpēc ienirstiet un izpētiet tipdrošu stāvokļu mašīnu pasauli ar TypeScript!