Průniky
Boss je příšera s něčím navíc: bojuje ve fázích a dává velkou odměnu. V lekci o typech objektů byste napsali interface Boss extends Prisera { … }. S type se totéž zapíše pomocí &:
type Prisera = {
jmeno: string;
zivoty: number;
utok: number;
};
type Boss = Prisera & { faze: number; odmena: number };
const drak: Boss = { jmeno: "Drak", zivoty: 300, utok: 25, faze: 1, odmena: 500 };
console.log(`${drak.jmeno}: životy ${drak.zivoty}, fáze ${drak.faze}`);Vypíše:
Drak: životy 300, fáze 1A & B je průnik typů (anglicky intersection): hodnota tohoto typu musí být zároveň A i B, takže má všechny vlastnosti typu A a všechny vlastnosti typu B. Název možná zní divně, protože průnik bývá menší, ne větší. Ubude ale hodnot: zbudou jen objekty, které odpovídají oběma typům. A takové objekty mají vlastností víc.
Porovnejte to se sjednocením z lekce o sjednocených typech. A | B je jedno, nebo druhé, takže dokud typ nezúžíte, můžete používat jen to, co mají oba. A & B je obojí najednou, takže můžete používat všechno.
Když bossovi něco chybí, hláška řekne, která část průniku to chce:
const troll: Boss = { jmeno: "Troll", zivoty: 80, utok: 9 };main.ts(10,7): error TS2322: Type '{ jmeno: string; zivoty: number; utok: number; }' is not assignable to type 'Boss'.
Type '{ jmeno: string; zivoty: number; utok: number; }' is missing the following properties from type '{ faze: number; odmena: number; }': faze, odmenaBoss je zároveň Prisera, takže ho můžete použít všude, kde se čeká příšera, třeba v poli Prisera[], stejně jako u extends.
Co tedy použít? U objektových typů udělají obojí stejnou práci. interface … extends bývá přehlednější a spor ohlásí hned tam, kde rozhraní deklarujete: kdyby Prisera měla id: number a boss id: string, dostali byste Interface 'Boss' incorrectly extends interface 'Prisera'. Průnik spor neohlásí a z typu té vlastnosti se stane never, typ bez hodnot. Přijdete na to, až když vytváříte objekt: Type 'number' is not assignable to type 'never'. Na druhou stranu & spojí jakékoli typy, třeba dva, které už máte, type Zoldner = Hrdina & Obchodnik;, nebo typ s pomocným typem, Omit<Hrdina, "id"> & { prijat: number }.
Typická chyba je | místo &. S type Boss = Prisera | { faze: number }; je boss jen jedním z obou typů a boss.faze skončí chybou:
main.ts(10,17): error TS2339: Property 'faze' does not exist on type 'Boss'.
Property 'faze' does not exist on type 'Prisera'.Jak psát:
Pokyny
Pod typ Prisera vytvořte typ Boss: příšeru se dvěma vlastnostmi navíc, faze a odmena, obě čísla. Použijte &.
Pod příšerami vytvořte konstantu drak typu Boss: Draka s 300 životy, útokem 25, ve fázi 1 a s odměnou 500. Pak napište funkci popisBosse(boss: Boss): string a vypište, co vrátí pro draka:
Drak (životy 300, útok 25), fáze 1, odměna 500 zlatýchPod to vytvořte konstantu prisery typu Prisera[] se skřetem, vlkem a drakem a v cyklu for...of vypište jméno a útok každé příšery:
Skřet: útok 3
Vlk: útok 5
Drak: útok 25Začněte programovat zdarma
6/7