Sjednocení literálů
Spousta hodnot ve hře pochází z krátkého, pevně daného seznamu. Hrdina je válečník, mág, nebo hraničář; na mapě jdete na sever, na jih, na východ, nebo na západ. Jako text je taková hodnota string, jenže string může být jakýkoli text, i s překlepem:
function pocatecniZivoty(povolani: string): number {
if (povolani === "valecnik") {
return 120;
} else if (povolani === "mag") {
return 70;
} else {
return 90;
}
}
console.log(pocatecniZivoty("valecnki"));Program vypíše 90, tedy životy hraničáře, protože "valecnki" není "valecnik". Žádná chyba, jen špatné číslo někde ve hře, a příčinu pak můžete hledat hodně dlouho.
V lekci Základní typy jste viděli, že literálový typ, třeba "tezka", dovoluje přesně jednu hodnotu. Pomocí | můžete několik literálových typů spojit do sjednocení literálů a pojmenovat ho pomocí type:
type Povolani = "valecnik" | "mag" | "hranicar";Povolani je jeden z těchto tří textů a nic jiného. Dejte tenhle řádek na začátek programu výše, změňte parametr na povolani: Povolani a TypeScript zkontroluje každé volání:
main.ts(13,29): error TS2345: Argument of type '"valecnki"' is not assignable to parameter of type 'Povolani'.Uvozovky uvnitř uvozovek znamenají přesně text "valecnki", jak to znáte u literálových typů. Stejná ochrana funguje všude, kde typ použijete. U proměnné vám TypeScript dokonce napoví, co jste nejspíš mysleli:
type Povolani = "valecnik" | "mag" | "hranicar";
let zvolene: Povolani = "valecnki";main.ts(3,5): error TS2820: Type '"valecnki"' is not assignable to type 'Povolani'. Did you mean '"valecnik"'?A kontroluje i porovnání. Kdyby byl překlep ve funkci, v if (povolani === "valecnki"), TypeScript by ohlásil:
main.ts(4,9): error TS2367: This comparison appears to be unintentional because the types 'Povolani' and '"valecnki"' have no overlap.„No overlap“ znamená, že se typy nepřekrývají: žádná hodnota není zároveň Povolani i text "valecnki", takže porovnání nemůže nikdy platit.
Jedna věc vás možná překvapí. Když je povolání v proměnné let bez typu, je volání chyba, přestože "mag" povolání je. S těmito dvěma řádky pod funkcí:
let volba = "mag";
console.log(pocatecniZivoty(volba));main.ts(14,29): error TS2345: Argument of type 'string' is not assignable to parameter of type 'Povolani'.TypeScript odvodil pro proměnnou volba typ string, stejně jako pro každé let s textem: později do ní můžete uložit jakýkoli jiný text. Buď proměnné typ dejte, let volba: Povolani = "mag";, nebo použijte const: typ const volba = "mag" je literálový typ "mag", a ten se do parametru hodí.
Poznámka do budoucna: v jiných jazycích a ve starším kódu v TypeScriptu můžete takové seznamy vidět zapsané jako enum (výčtový typ), třeba enum Smer { Sever, Jih }. Na rozdíl od ostatních typů enum po odstranění typů nezmizí: stane se z něj kus kódu v JavaScriptu. Proto ho nastavení tohoto webu nedovoluje:
main.ts(1,6): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.V novějším kódu v TypeScriptu ho často nahrazují sjednocení literálů, jaká teď píšete i vy.
Jak psát:
Pokyny
Program třikrát vypíše 90, ale válečník má začínat se 120 životy a mág se 70. Nad funkcí vytvořte typ Povolani pro tři povolání "valecnik", "mag" a "hranicar" a použijte ho jako typ parametru povolani. TypeScript pak najde dva překlepy: opravte je, aby program vypsal:
120
70
90Pod volání vytvořte typ Hrdina pro objekt s vlastnostmi jmeno (text) a povolani typu Povolani. Pak vytvořte konstantu kira typu Hrdina: jmenuje se "Kira" a její povolání je "hranicar".
Vypište řádek o Kiře pomocí jejích vlastností a funkce pocatecniZivoty. Program pak vypíše:
120
70
90
Kira začíná s 90 životyZačněte programovat zdarma
3/10