Stavy úkolů
Rozlišené sjednocení se nehodí jen pro různé druhy věcí, ale i pro různé stavy jedné věci. Úkol v Kiřině deníku může být otevřený, splněný, nebo neúspěšný, a každý stav má vlastní data: splněný úkol má odměnu, neúspěšný důvod, proč se nepovedl, a otevřený nemá ani jedno:
type Ukol =
| { stav: "otevreny"; nazev: string }
| { stav: "splneny"; nazev: string; odmena: number }
| { stav: "neuspesny"; nazev: string; duvod: string };Značka se tu jmenuje stav, protože popisuje stav úkolu. Název je na vás; jen to musí být stejná vlastnost ve všech členech sjednocení a v každém s jiným literálovým typem. Takhle dlouhé sjednocení se lépe čte na víc řádcích. Pak můžete | napsat před každého člena, i před prvního: svislou čáru na úplném začátku TypeScript ignoruje.
Typ říká přesně to, co o každém úkolu víte. Odměnu má jen splněný úkol, a tak je čtení ukol.odmena bez kontroly chyba:
type Ukol =
| { stav: "otevreny"; nazev: string }
| { stav: "splneny"; nazev: string; odmena: number }
| { stav: "neuspesny"; nazev: string; duvod: string };
const ukoly: Ukol[] = [
{ stav: "splneny", nazev: "Vlci v lese", odmena: 50 },
{ stav: "otevreny", nazev: "Ztracená koruna" },
{ stav: "neuspesny", nazev: "Záchrana mlynáře", duvod: "mlýn vyhořel" },
];
for (const ukol of ukoly) {
console.log(`${ukol.nazev}: ${ukol.odmena} zlatých`);
}main.ts(13,40): error TS2339: Property 'odmena' does not exist on type 'Ukol'.
Property 'odmena' does not exist on type '{ stav: "otevreny"; nazev: string; }'.Druhý řádek hlášky dokonce říká, který úkol odměnu nemá: otevřený. A úkol, který nedává smysl, nejde vůbec zapsat: const koruna: Ukol = { stav: "otevreny", nazev: "Ztracená koruna", odmena: 100 }; skončí chybou error TS2353: Object literal may only specify known properties, and 'odmena' does not exist in type '{ stav: "otevreny"; nazev: string; }'.
Vlastnost nazev mají všichni tři členové, takže ji můžete číst u každého úkolu. U ostatních nejdřív zkontrolujte stav:
for (const ukol of ukoly) {
if (ukol.stav === "splneny") {
console.log(`${ukol.nazev}: ${ukol.odmena} zlatých`);
} else {
console.log(`${ukol.nazev}: bez odměny`);
}
}Vypíše:
Vlci v lese: 50 zlatých
Ztracená koruna: bez odměny
Záchrana mlynáře: bez odměnyPorovnejte to s jedním typem s nepovinnými vlastnostmi, { stav: string; nazev: string; odmena?: number; duvod?: string }. Ten dovolí otevřený úkol s odměnou, splněný úkol bez ní, a dokonce stav "slpneny". Právě o takových typech je další cvičení.
Jak psát:
Pokyny
Spusťte program: třetí úkol do typu nezapadá. Přidejte do sjednocení Ukol třetího člena: neúspěšný úkol se stav: "neuspesny", s vlastností nazev a s vlastností duvod (obě jsou texty).
Napište funkci popisUkolu s parametrem ukol typu Ukol, která vrátí popis úkolu. Použijte switch podle ukol.stav (s kontrolou úplnosti ve větvi default, ať si ji procvičíte) a vypište popis každého úkolu. Program pak vypíše:
Vlci v lese: splněno, +50 zlatých
Ztracená koruna: probíhá
Záchrana mlynáře: nezdar (mlýn vyhořel)
Skřetí most: splněno, +30 zlatýchSečtěte odměny splněných úkolů a na konci vypište součet:
Vlci v lese: splněno, +50 zlatých
Ztracená koruna: probíhá
Záchrana mlynáře: nezdar (mlýn vyhořel)
Skřetí most: splněno, +30 zlatých
Odměny celkem: 80 zlatýchZačněte programovat zdarma
6/8