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ž je Hrdina typ, skončí chybou 'Hrdina' only refers to a type, but is being used as a value here. Typ nemá žádnou hodnotu, ze které by šel typeof vzít. Použijte rovnou typ Hrdina.

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

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

Nebo se registrujte pomocí:

5/7