Partial
Hrdinové se pořád mění: postoupí na vyšší úroveň, v boji přijdou o životy, najdou zlato. Většinou se změní jen jedna nebo dvě vlastnosti a zbytek zůstane, jak byl. V této lekci poznáte pomocné typy (anglicky utility types): generické typy zabudované přímo v TypeScriptu, které z typu, který už máte, vyrobí nový. Jeden z nich už znáte: Record<K, V>. První nový se hodí právě na takové změny. Nejdřív ale jedna novinka z JavaScriptu, kterou k tomu budete potřebovat.
Spread. Tři tečky před objektem uvnitř složených závorek, { ...kira }, zkopírují všechny jeho vlastnosti do nového objektu. Tomuto zápisu se říká spread (z angličtiny, „rozprostřít“). Vlastnosti napsané za ním se do nového objektu přidají, nebo nahradí zkopírované vlastnosti se stejným názvem:
const kira = { jmeno: "Kira", uroven: 3, zlato: 120 };
const silnejsi = { ...kira, uroven: 4 };
console.log(silnejsi);
console.log(kira);Vypíše:
{ jmeno: "Kira", uroven: 4, zlato: 120 }
{ jmeno: "Kira", uroven: 3, zlato: 120 }Původní objekt zůstal, jaký byl: spread vytvoří nový. Rozprostřít můžete i několik objektů, { ...a, ...b }. Když mají oba vlastnost se stejným názvem, vyhraje ta, která je napsaná později, tady ta z b. Tři tečky fungují i v polích: [...korist, "Stará mapa"] je nové pole se vším, co je v korist, a s jedním předmětem navíc na konci.
Partial. Teď funkce, která hrdinu upraví: dostane hrdinu a změny a vrátí nového, upraveného hrdinu. Jaký typ ale mají mít změny? S typem Hrdina chce TypeScript všechny jeho vlastnosti, i když chcete změnit jen dvě:
interface Hrdina {
jmeno: string;
uroven: number;
zivoty: number;
zlato: number;
}
function upravHrdinu(hrdina: Hrdina, zmeny: Hrdina): Hrdina {
return { ...hrdina, ...zmeny };
}
const kira: Hrdina = { jmeno: "Kira", uroven: 3, zivoty: 50, zlato: 120 };
const poUkolu = upravHrdinu(kira, { uroven: 4, zlato: 160 });main.ts(13,35): error TS2739: Type '{ uroven: number; zlato: number; }' is missing the following properties from type 'Hrdina': jmeno, zivotyMohli byste napsat druhý typ, ve kterém je každá vlastnost nepovinná. Jenže pak byste při každé změně typu Hrdina museli upravit oba. Partial<Hrdina> to udělá za vás: je to Hrdina, ve kterém je každá vlastnost nepovinná, jako byste napsali jmeno?: string, uroven?: number a tak dál. S parametrem zmeny: Partial<Hrdina> funkce přijme { uroven: 4, zlato: 160 }, jedinou vlastnost, nebo dokonce {}. A když do typu Hrdina přidáte novou vlastnost, bude ji mít i Partial<Hrdina>.
Nepovinné ale neznamená, že projde cokoli. Názvy a typy vlastností TypeScript kontroluje dál:
upravHrdinu(kira, { zivtoy: 60 });
upravHrdinu(kira, { zivoty: "60" });main.ts(13,21): error TS2561: Object literal may only specify known properties, but 'zivtoy' does not exist in type 'Partial<Hrdina>'. Did you mean to write 'zivoty'?
main.ts(14,21): error TS2322: Type 'string' is not assignable to type 'number'.Uvnitř funkce může kterákoli vlastnost objektu zmeny chybět, takže její typ zahrnuje i undefined, stejně jako u nepovinných vlastností v lekci o typech objektů. Zápis { ...hrdina, ...zmeny } si s tím poradí: co v zmeny chybí, nic nepřepíše, a hrdinovi zůstane původní hodnota.
Typické chyby:
- Obrácené pořadí,
{ ...zmeny, ...hrdina }. Staré hodnoty hrdiny jsou až na konci, takže změny přepíšou, a nezmění se nic. Změny patří vždycky na konec. - Vlastnost napsaná před spreadem, který ji obsahuje taky. V
{ uroven: 4, ...kira }by Kiřina vlastníurovenčtyřku přepsala, a TypeScript proto ohlásí:main.ts(2,20): error TS2783: 'uroven' is specified more than once, so this usage will be overwritten.
Jak psát:
Pokyny
Pod konstantu kira napište funkci upravHrdinu(hrdina: Hrdina, zmeny: Partial<Hrdina>): Hrdina, která vrátí nového hrdinu, { ...hrdina, ...zmeny }.
Kira splnila úkol: postoupila na úroveň 4 a má 160 zlatých. Pod funkcí uložte upravHrdinu(kira, { uroven: 4, zlato: 160 }) do konstanty poUkolu a vypište ji:
{ jmeno: "Kira", uroven: 4, zivoty: 50, zlato: 160 }Pod to vypište i kira. Původní objekt se nezměnil:
{ jmeno: "Kira", uroven: 4, zivoty: 50, zlato: 160 }
{ jmeno: "Kira", uroven: 3, zivoty: 50, zlato: 120 }Začněte programovat zdarma
1/7