Zužování pomocí typeof
Funkce, která dostane string | number, obvykle potřebuje s každým typem zacházet jinak. V JavaScriptu typ zjistíte pomocí typeof, které znáte z kurzu JavaScriptu: typeof 50 je "number" a typeof "Stříbrný meč" je "string". TypeScript takové kontrole rozumí. V tomhle příkladu vyplácí cech odměny za úkoly a z každé odměny ve zlatě si 5 zlatých nechá pro sebe:
function vyplata(odmena: string | number): string {
if (typeof odmena === "string") {
return `Dostáváte ${odmena.toUpperCase()}`;
} else {
return `Dostáváte ${odmena - 5} zlatých (5 pro cech)`;
}
}
console.log(vyplata("Stříbrný meč"));
console.log(vyplata(50));Vypíše:
Dostáváte STŘÍBRNÝ MEČ
Dostáváte 45 zlatých (5 pro cech)Uvnitř if TypeScript ví, že odmena je string, a proto dovolí toUpperCase(). Ve větvi else zbývá jen number, a tak dovolí odčítání. Tomu se říká zužování typu (anglicky narrowing): kontrola typ uvnitř větve zúží, ze string | number jen na string, nebo jen na number.
Bez kontroly TypeScript odčítání nedovolí:
function vyplata(odmena: string | number): string {
return `Dostáváte ${odmena - 5} zlatých (5 pro cech)`;
}main.ts(2,25): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.Tuhle hlášku znáte z lekce Základní typy: hodnota vlevo od - musí být číslo.
Zužování funguje i bez větve else. Když větev if skončí příkazem return, zbytek funkce se provede jen pro druhý typ, a TypeScript to ví:
function vyplata(odmena: string | number): string {
if (typeof odmena === "string") {
return `Dostáváte ${odmena.toUpperCase()}`;
}
return `Dostáváte ${odmena - 5} zlatých (5 pro cech)`;
}Pod podmínkou je odmena typu number. Programátoři funkce často píšou právě takhle: nejdřív zvláštní případ, který skončí příkazem return, a pak hlavní případ bez dalších složených závorek.
Sjednocení se objevují i v polích. Typ pole [12, "Starý klíč", 40] TypeScript odvodí jako (string | number)[]: pole, jehož prvky jsou texty nebo čísla. Když takový typ píšete sami, nezapomeňte na kulaté závorky. Bez nich znamená number | string[] „číslo, nebo pole textů“ a TypeScript čísla v poli odmítne:
const korist: number | string[] = [12, "Starý klíč", 40];main.ts(1,36): error TS2322: Type 'number' is not assignable to type 'string'.
main.ts(1,54): error TS2322: Type 'number' is not assignable to type 'string'.Typické chyby:
typeofvrací název typu malými písmeny:"string","number","boolean". Natypeof odmena === "String"TypeScript ohlásíerror TS2367: This comparison appears to be unintentional because the types '"bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"' and '"String"' have no overlap.Dlouhý seznam v hlášce ukazuje všechny texty, které můžetypeofvrátit, a"String"mezi nimi není.- Zúžený typ platí jen uvnitř větve, nebo pod podmínkou, která skončí příkazem
return. Pod podmínkou bezreturnje typ zasestring | number.
Jak psát:
Pokyny
Spusťte program: TypeScript nedovolí cena * pocet, protože cena může být text. Na začátek funkce formatujCenu přidejte kontrolu pomocí typeof: když je cena text, funkce ho vrátí velkými písmeny. Program pak vypíše:
50 zlatých
ZDARMAPod volání vytvořte pole ceny typu (number | string)[] s hodnotami 12, "vyprodáno" a 40.
Projděte pole ceny cyklem for...of a pro každou cenu vypište formatujCenu(cena, 2). Program pak vypíše:
50 zlatých
ZDARMA
24 zlatých
VYPRODÁNO
80 zlatýchZačněte programovat zdarma
2/10