Typ pro výsledek

Některé funkce můžou selhat. Nákup v obchodě se nepovede, když tam předmět nemají nebo když na něj hrdina nemá dost zlata. Funkce by při neúspěchu mohla vrátit undefined, jenže pak ten, kdo ji volá, neví proč. Spojte dvě věci, které znáte, rozlišené sjednocení (lekce 6) a typový parametr, a máte typ pro výsledek čehokoli, co může selhat:

type Vysledek<T> = { ok: true; hodnota: T } | { ok: false; chyba: string };

Vysledek<T> je buď úspěch, který má vlastnost hodnota typu T, nebo neúspěch s chybovou zprávou ve vlastnosti chyba. Rozlišuje je vlastnost ok. Její typy jsou literálové typy true a false: stejně jako "lektvar" dovolují jen tu jednu hodnotu. Jeden typ stačí pro všechny funkce, které můžou selhat: Vysledek<number>, Vysledek<Hrdina> a tak dál.

type Vysledek<T> = { ok: true; hodnota: T } | { ok: false; chyba: string };

function rozdelZlato(zlato: number, hrdinove: number): Vysledek<number> {
    if (hrdinove === 0) {
        return { ok: false, chyba: "není s kým se dělit" };
    }
    return { ok: true, hodnota: zlato / hrdinove };
}

const podil = rozdelZlato(120, 3);
if (podil.ok) {
    console.log(`Každý hrdina dostane ${podil.hodnota} zlatých`);
} else {
    console.log(`Nelze rozdělit: ${podil.chyba}`);
}

Vypíše:

Každý hrdina dostane 40 zlatých

Uvnitř if (podil.ok) TypeScript ví, že jde o úspěch, takže podil.hodnota je číslo. Ve větvi else jde o neúspěch, který má vlastnost chyba. Před kontrolou může být podil cokoli z obojího, a tak je čtení hodnota chyba. Přidejte na konec console.log(rozdelZlato(120, 0).hodnota); a TypeScript ohlásí:

main.ts(16,33): error TS2339: Property 'hodnota' does not exist on type 'Vysledek<number>'.
  Property 'hodnota' does not exist on type '{ ok: false; chyba: string; }'.

Druhý řádek to vysvětluje: neúspěch žádnou vlastnost hodnota nemá. A přesně o to jde: na neúspěch nejde zapomenout. TypeScript donutí každého, kdo funkci volá, aby se postaral o oba případy, stejně jako u výsledku find typu Predmet | undefined v lekci 5. Vysledek ale navíc nese chybovou zprávu, která řekne, co se pokazilo. Tenhle vzor používá spousta programů v TypeScriptu.

Typické chyby:

  • Smíchané případy: return { ok: true, chyba: "…" }; skončí chybou Object literal may only specify known properties, and 'chyba' does not exist in type '{ ok: true; hodnota: number; }'. (TS2353).
  • ok: "true" (text) místo ok: true.
  • Chybějící typový argument: samotné Vysledek dá TS2314, Generic type 'Vysledek' requires 1 type argument(s).

Pokyny

Pod obchodem deklarujte typ Vysledek<T> přesně jako výše: { ok: true; hodnota: T }, nebo { ok: false; chyba: string }.

Napište funkci kupPredmet(obchod: Predmet[], jmeno: string, zlato: number): Vysledek<Predmet>. Ta najde předmět podle jména pomocí find. Když ho obchod nemá, selže s chybou `${jmeno} v obchodě nemají`. Když předmět stojí víc než zlato, selže s chybou `na ${jmeno} nestačí zlato`. Jinak uspěje a hodnotou bude nalezený předmět.

Kira má 50 zlatých a zkusí koupit tři věci. Na konec programu přidejte tento cyklus:

for (const jmeno of ["Léčivý lektvar", "Stříbrný meč", "Dračí vejce"]) {
    const vysledek = kupPredmet(obchod, jmeno, 50);
    if (vysledek.ok) {
        console.log(`Koupeno: ${vysledek.hodnota.jmeno}`);
    } else {
        console.log(`Nepovedlo se: ${vysledek.chyba}`);
    }
}

Program vypíše:

Koupeno: Léčivý lektvar
Nepovedlo se: na Stříbrný meč nestačí zlato
Nepovedlo se: Dračí vejce v obchodě nemají

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

6/9