Typy z hodnot
Obvykle napíšete nejdřív typ a pak hodnoty, které mu odpovídají. Někdy je to ale naopak: nejdřív je hodnota a typ se má řídit podle ní. Každý nový hrdina začíná se stejnými schopnostmi, zapsanými jednou v objektu:
const zakladniSchopnosti = { sila: 5, obratnost: 5, magie: 5 };Funkce, které se schopnostmi pracují, pro ně potřebují typ. Mohli byste ručně napsat { sila: number; obratnost: number; magie: number }, jenže pak byste ho museli upravit při každé změně objektu. TypeScript umí typ vzít přímo z hodnoty:
const zakladniSchopnosti = { sila: 5, obratnost: 5, magie: 5 };
type Schopnosti = typeof zakladniSchopnosti;
const schopnostiMaga: Schopnosti = { sila: 2, obratnost: 4, magi: 9 };main.ts(4,61): error TS2561: Object literal may only specify known properties, but 'magi' does not exist in type '{ sila: number; obratnost: number; magie: number; }'. Did you mean to write 'magie'?Schopnosti je typ, který TypeScript odvodil pro zakladniSchopnosti, tedy { sila: number; obratnost: number; magie: number; }, a tak ho hláška i vypíše. Vlastnosti jsou typu number, ne 5, protože vlastnosti objektu se mohou měnit. Když do zakladniSchopnosti přidáte vlastnost, dostane ji i typ Schopnosti a TypeScript ohlásí každý objekt typu Schopnosti, který ji zatím nemá.
typeof znáte z JavaScriptu: typeof zlato === "number". Ten typeof pracuje za běhu programu a výsledkem je text, třeba "number" nebo "object". V typu (za type Schopnosti = nebo za dvojtečkou) patří typeof TypeScriptu: dá typ proměnné a jako každý typ z programu zmizí. Už jste ho použili v lekci Modelování dat: (typeof vsechnaPovolani)[number].
const zakladniSchopnosti = { sila: 5, obratnost: 5, magie: 5 };
type Schopnosti = typeof zakladniSchopnosti;
const kopie: Schopnosti = { ...zakladniSchopnosti };
console.log(typeof kopie);
console.log(kopie);Vypíše:
object
{ sila: 5, obratnost: 5, magie: 5 }Hodnoty a typy žijí ve dvou oddělených světech. zakladniSchopnosti je hodnota (proměnná), Schopnosti je typ a typeof přenese typ hodnoty do světa typů. Samotnou proměnnou zakladniSchopnosti typem Schopnosti anotovat nemůžete, protože typ vzniká až z ní.
Typické chyby:
- Chybí
typeof,type Schopnosti = zakladniSchopnosti;. Hláška poradí, co napsat:main.ts(2,19): error TS2749: 'zakladniSchopnosti' refers to a value, but is being used as a type here. Did you mean 'typeof zakladniSchopnosti'? - Naopak:
typeof Hrdina, když jeHrdinatyp, skončí chybou'Hrdina' only refers to a type, but is being used as a value here.Typ nemá žádnou hodnotu, ze které by šeltypeofvzít. Použijte rovnou typHrdina.
Jak psát:
Pokyny
Pod zakladniSchopnosti vytvořte typ type Schopnosti = typeof zakladniSchopnosti;. Použijte ho ve funkci sectiSchopnosti pro oba parametry i pro návratový typ místo tří dlouhých typů a anotujte jím i bonusValecnika a bonusMaga. Program vypíše totéž co předtím.
Hrdinové dostanou novou schopnost, štěstí. Přidejte do zakladniSchopnosti vlastnost stesti: 1 a spusťte program. Typ Schopnosti teď má i stesti a TypeScript ohlásí tři místa, kde zatím chybí, s chybami, jako je tahle:
main.ts(6,7): error TS2741: Property 'stesti' is missing in type '{ sila: number; obratnost: number; magie: number; }' but required in type '{ sila: number; obratnost: number; magie: number; stesti: number; }'.Opravte všechna tři: válečník dostane bonus ke štěstí 0, mág 2, a funkce sectiSchopnosti sečte i štěstí. Program vypíše:
{ sila: 9, obratnost: 6, magie: 5, stesti: 1 }
{ sila: 5, obratnost: 6, magie: 10, stesti: 3 }Začněte programovat zdarma
5/7