Typové stráže
typeof rozliší texty od čísel. Co ale sjednocení dvou typů objektů? Pro oba vrátí typeof stejně "object":
type Lektvar = { nazev: string; leceni: number };
type Zbran = { nazev: string; poskozeni: number };
type Predmet = Lektvar | Zbran;
const inventar: Predmet[] = [
{ nazev: "Léčivý lektvar", leceni: 20 },
{ nazev: "Stříbrný meč", poskozeni: 12 },
];U předmětu typu Predmet smíte číst nazev, který mají oba typy, ale ne leceni. V cyklu for (const predmet of inventar) skončí řádek console.log(predmet.leceni); chybou:
main.ts(11,25): error TS2339: Property 'leceni' does not exist on type 'Predmet'.
Property 'leceni' does not exist on type 'Zbran'.JavaScript má operátor, který zjistí, jestli má objekt nějakou vlastnost: "leceni" in predmet je true, když má predmet vlastnost leceni. TypeScript podle něj typ zužuje. Vlastnost leceni má jen Lektvar, takže uvnitř if je předmět typu Lektvar a ve větvi else typu Zbran:
for (const predmet of inventar) {
if ("leceni" in predmet) {
console.log(`${predmet.nazev} léčí ${predmet.leceni}`);
} else {
console.log(`${predmet.nazev} má poškození ${predmet.poskozeni}`);
}
}Vypíše:
Léčivý lektvar léčí 20
Stříbrný meč má poškození 12Když stejnou kontrolu potřebujete na víc místech, budete ji chtít dát do funkce. Funkce, která vrací boolean, ale nic nezúží:
function jeLektvar(predmet: Predmet): boolean {
return "leceni" in predmet;
}
for (const predmet of inventar) {
if (jeLektvar(predmet)) {
console.log(`${predmet.nazev} léčí ${predmet.leceni}`);
}
}TypeScript zase ohlásí Property 'leceni' does not exist on type 'Predmet'. Z návratového typu boolean se dozví jen to, že funkce vrací true nebo false, ne co to říká o předmětu. K tomu slouží zvláštní návratový typ predmet is Lektvar („předmět je lektvar“):
function jeLektvar(predmet: Predmet): predmet is Lektvar {
return "leceni" in predmet;
}Funkce dál vrací true nebo false, ale TypeScript teď ví: když vrátí true, je predmet typu Lektvar. Takové funkci se říká typová stráž (anglicky type guard). Podmínka if (jeLektvar(predmet)) pak typ zúží stejně jako kontrola in uvnitř funkce a ve větvi else je předmět typu Zbran. Před is stojí název parametru.
(Když návratový typ úplně vynecháte, současné verze TypeScriptu si predmet is Lektvar někdy odvodí samy. S : boolean jste jim ale řekli, že jde jen o pravdivostní hodnotu.)
Typické chyby:
- TypeScript typové stráži věří: nekontroluje, jestli tělo funkce testuje správnou věc. Když omylem napíšete
return "poskozeni" in predmet;, TypeScript bude považovat meče za lektvary a cyklus výše vypíšeStříbrný meč léčí undefined. - Překlep v názvu vlastnosti TypeScript také neohlásí.
"lecen" in predmetje prostě u každého předmětufalse, takže žádný předmět nikdy nebude lektvar.
V příští lekci uvidíte častější způsob, jak typy objektů rozlišit: vlastnost jako druh, která říká, co je každý objekt zač. Tam TypeScript takové překlepy zachytí.
Jak psát:
Pokyny
V bitvě jsou hrdinové i příšery. Napište typovou stráž jePrisera s parametrem bojovnik typu Bojovnik: pomocí in zjistí, jestli je bojovník Prisera.
Projděte pole bitva cyklem for...of a pomocí jePrisera vypište každého bojovníka: příšeru s její silou, hrdinu s úrovní. Program pak vypíše:
Kira (úroveň 3)
skřet (síla 4)
Bruno (úroveň 2)
troll (síla 15)Sečtěte sílu všech příšer a za cyklem ji vypište:
Kira (úroveň 3)
skřet (síla 4)
Bruno (úroveň 2)
troll (síla 15)
Síla příšer: 19Začněte programovat zdarma
9/10