Tilakoneiden mallintaminen
Esittäkää rajalliset tilat diskriminoitujen unionien avulla.
Tilakoneiden mallintaminen on ilmainen TypeScript Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu TypeScript Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. TypeScript Academy-kurssilla on yhteensä 4 oppituntia.
Tilat diskriminoituna unionina
Käyttöliittymillä ja asynkronisilla työnkuluilla on erillisiä tiloja: idle, loading, success ja error. Kun mallinnat ne diskriminoituna unionina, jokainen tila sisältää täsmälleen tarvitsemansa tiedot.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
const s: State = { status: "idle" };
console.log(s.status);Tiedot kullekin tilalle
Vain success-tilalla on data; vain error-tilalla on message. Idle- ja loading-tilat eivät sisällä ylimääräisiä tietoja, mikä estää vanhentuneiden tietojen vuotamisen tilasta toiseen.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: number[] }
| { status: "error"; message: string };
const ok: State = { status: "success", data: [1, 2, 3] };
console.log(ok.status, "data" in ok ? ok.data : null);Kunkin tilan näyttäminen
status-arvon perusteella haarautuva funktio voi näyttää kullekin tilalle oikean tuloksen. Jäsenkohtaiset kentät ovat käytettävissä vain siellä, missä ne todella ovat olemassa.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
function view(s: State): string {
switch (s.status) {
case "idle": return "Ready";
case "loading": return "Loading...";
case "success": return "Got: " + s.data;
case "error": return "Failed: " + s.message;
}
}
console.log(view({ status: "success", data: "users" }));Siirtymien määrittäminen
Tilakone siirtyy tilasta toiseen siirtymien avulla. Siirtymäfunktio ottaa vastaan nykyisen tilan ja tapahtuman ja palauttaa seuraavan tilan.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
function start(s: State): State {
if (s.status === "idle") return { status: "loading" };
return s;
}
console.log(start({ status: "idle" }).status);Myös tapahtumien mallintaminen
Myös tapahtumat voivat muodostaa diskriminoidun unionin. Kukin tapahtumatyyppi käynnistää tietyn siirtymän.
type Event =
| { type: "FETCH" }
| { type: "RESOLVE"; data: string }
| { type: "REJECT"; message: string };
const e: Event = { type: "RESOLVE", data: "ok" };
console.log(e.type);Täydellinen siirtymäfunktio
Yhdistä tila- ja tapahtumaunionit yhteen reduceria käyttävään toteutukseen. Molempien perusteella haarautuminen pitää jokaisen siirtymän eksplisiittisenä ja tyyppiturvallisena.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
type Event =
| { type: "FETCH" }
| { type: "RESOLVE"; data: string }
| { type: "REJECT"; message: string };
function reduce(s: State, e: Event): State {
if (e.type === "FETCH") return { status: "loading" };
if (e.type === "RESOLVE") return { status: "success", data: e.data };
return { status: "error", message: e.message };
}
console.log(reduce({ status: "idle" }, { type: "FETCH" }).status);Virheellisiä tiloja ei voi esittää
Sinulla ei voi olla data-arvoa ja error message-arvoa samanaikaisesti. Unionin rakenne estää ristiriitaiset tilat jo muodostusvaiheessa.
type State =
| { status: "success"; data: string }
| { status: "error"; message: string };
// const bad: State = { status: "success", data: "x", message: "y" };
// Allowed extra props would be flagged in strict object checks.
console.log("no contradictory states");Virheellisten siirtymien estäminen
Voit ohittaa tapahtumat, jotka eivät koske nykyistä tilaa. Näin kone pysyy johdonmukaisessa tilassa kaatumisen sijaan.
type State = { status: "idle" } | { status: "loading" };
type Event = { type: "FETCH" } | { type: "CANCEL" };
function reduce(s: State, e: Event): State {
if (s.status === "loading" && e.type === "CANCEL") return { status: "idle" };
if (s.status === "idle" && e.type === "FETCH") return { status: "loading" };
return s; // ignore invalid combos
}
console.log(reduce({ status: "loading" }, { type: "CANCEL" }).status);Kattavuuden lisääminen
Yhdistä reduceria käyttävään toteutukseen assertNever, jotta uuden tilan tai tapahtuman lisääminen paljastaa kaikki päivitettävät kohdat.
function assertNever(x: never): never { throw new Error("unhandled"); }
type State = { status: "idle" } | { status: "loading" } | { status: "done"; data: string };
function view(s: State): string {
switch (s.status) {
case "idle": return "idle";
case "loading": return "loading";
case "done": return s.data;
default: return assertNever(s);
}
}
console.log(view({ status: "done", data: "ok" }));Alku- ja lopputilat
Määritä selkeä alkutila, usein idle, sekä lopputilat, kuten success tai error. Näin dokumentoit tilakoneen elinkaaren.
type State =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
const initial: State = { status: "idle" };
console.log("Start:", initial.status);Täydellinen pieni tilakone
Tässä on koko kierto: aloita idle-tilasta, siirry fetch-toiminnolla loading-tilaan ja ratkaise tilaksi success. Tyypit pitävät jokaisen vaiheen johdonmukaisena.
type State = { status: "idle" } | { status: "loading" } | { status: "success"; data: string };
type Event = { type: "FETCH" } | { type: "RESOLVE"; data: string };
function reduce(s: State, e: Event): State {
if (e.type === "FETCH") return { status: "loading" };
return { status: "success", data: e.data };
}
let st: State = { status: "idle" };
st = reduce(st, { type: "FETCH" });
st = reduce(st, { type: "RESOLVE", data: "hi" });
console.log(st.status, st.status === "success" ? st.data : "");Pikatarkistus: tilakoneet
Testaa, miten hyvin ymmärrät tilakoneiden mallintamisen.
Kertaus: tilakoneiden mallintaminen
Mallinsit idle-, loading-, success- ja error-tilat diskriminoituna unionina, kirjoitit tyyppiturvalliset siirtymät tila- ja tapahtumaunioneille sekä käytit kattavuustarkistusta pitääksesi tilakoneen oikeellisena sen kasvaessa.
type State = { status: "idle" } | { status: "loading" } | { status: "success"; data: string };
const s: State = { status: "success", data: "done" };
console.log(s.status === "success" ? s.data : "");Opi TypeScript tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 101
- Oppitunnit
- 352
Usein kysytyt kysymykset
Onko oppitunti ”Tilakoneiden mallintaminen” ilmainen?
Kyllä – oppitunnin ”Tilakoneiden mallintaminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko TypeScript Academy-kurssin, päivitä CoddyKit PROhon. TypeScript Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Tilakoneiden mallintaminen”?
Esittäkää rajalliset tilat diskriminoitujen unionien avulla. Harjoittelet TypeScript Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni TypeScript Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin TypeScript Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Tilakoneiden mallintaminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä TypeScript Academy-oppitunnilla?
Kyllä. Jokainen TypeScript Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Diskriminoitujen unionien rakentaminen
- Tyypin supistaminen diskriminoijan perusteella
- Kattavuuden tarkistus never-tyypillä
- Tilakoneiden mallintaminen