Úvod do konverze typů v TypeScriptu
JavaScript byl původně zamýšlen jako nástroj pro tvorbu krátkých, několikřádkových útržků kódu, které se vkládaly do webových stránek. Nikdo tehdy netušil, jak obrovskou popularitu získá a že se bude využívat k budování komplexních aplikací o tisících řádcích kódu.
I když se JavaScript významně rozvinul a je dnes široce používán pro vývoj aplikací, nelze ho považovat za dokonalý jazyk. Jeho skromné začátky a původní účel způsobily, že má určité specifické rysy, které mohou tvorbu rozsáhlých aplikací značně zkomplikovat.
Například, JavaScript nevyvolá chybu, když se odkazujete na neexistující prvky objektu, nebo když násobíte hodnotu null numerickou hodnotou.
V JavaScriptu se prázdný řetězec („“) považuje za rovnocenný 0 (nule) při porovnání operátorem rovnosti (==). Horší je, že JavaScript vás na tyto chyby neupozorní během vývoje. Objeví se až po spuštění programu.
Z tohoto důvodu byl vyvinut TypeScript, který staví na základech JavaScriptu, aby zmírnil potíže vznikající při tvorbě aplikací v JavaScriptu. TypeScript provádí statickou typovou kontrolu v průběhu psaní kódu.
Statická kontrola znamená odhalování chyb v kódu bez nutnosti jeho spouštění. Statická typová kontrola tedy analyzuje chyby během vývoje na základě datových typů, se kterými kód pracuje.
TypeScript je typovaná nadmnožina jazyka JavaScript. To znamená, že každý platný JavaScriptový kód je zároveň i platným kódem v TypeScriptu. „Typovaný“ znamená, že TypeScript zavádí pravidla pro používání různých datových typů. TypeScript je navíc silně typovaný a nelze obcházet omezení vynucená typovým systémem.
TypeScript představuje velký krok vpřed a významný vývoj ve webovém vývoji. Umožňuje vytvářet čitelnější a snadno udržovatelný kód. Navíc podporuje správné postupy kódování a pomáhá vývojářům odhalovat a předcházet chybám v průběhu psaní kódu.
TypeScript je spolehlivější, snadněji se refaktoruje, a proto je pro tvorbu velkých aplikací ideálnější než JavaScript. Vzhledem k silné typové kontrole v TypeScriptu se dále zaměříme na konverzi typů, její význam a způsoby, jak ji TypeScript zpracovává.
Konverze datových typů v TypeScriptu a její význam
Konverze datového typu je proces převodu hodnoty z jednoho datového typu na jiný, například převod řetězce na číslo. Konverze typů může být implicitní, kdy překladač automaticky konvertuje kompatibilní datové typy během kompilace.
Konverze může být ale také explicitní, kdy je požadavek na konverzi typu výslovně uveden ve zdrojovém kódu. To se často označuje jako typové přetypování.
Konverze typů je důležitá, protože umožňuje vývojářům pracovat s různými formáty dat, a přitom stále splňovat požadavky datových typů v TypeScriptu. Pomáhá také zajišťovat předvídatelné výsledky ze zdrojového kódu.
Typové přetypování, které si sami vývojáři definují, pomáhá zajistit, že váš kód stále splňuje typové požadavky TypeScriptu. Díky tomu je kód čitelnější, srozumitelnější a pomáhá předcházet chybám souvisejícím s typy.
Převody typů také pomáhají ověřovat data a TypeScript tak může vývojářům pomáhat díky všem vestavěným nástrojům, jako je například automatické doplňování, které je svázané s konkrétními typy.
Běžným příkladem využití konverze typů je práce s řetězci a čísly. Při převodu řetězců na čísla v TypeScriptu se z důvodu prevence chyb v kódu převádějí pouze řetězce, které reprezentují čísla. To znamená, že můžete převádět řetězce jako „1“, „235“, „5234.5“, atd., ale nikoliv například řetězec „ahoj“.
Pojďme se podívat na různé způsoby, jakými lze v TypeScriptu převádět řetězce na čísla:
Typová aserce pomocí „as“
Při práci s různými datovými typy v kódu TypeScript se občas stane, že máte o typu hodnoty více informací, než může TypeScript zjistit. V takových případech můžete TypeScriptu explicitně sdělit typ proměnné, místo toho, aby ho odvozoval sám. Tomu se říká typová aserce.
Typová aserce se provádí pomocí klíčového slova as
. Chcete-li použít typovou aserci pro převod řetězce na číslo, je nejprve nutné nastavit typ řetězce na unknown
. Důvodem je, že standardně TypeScript považuje jakýkoliv převod řetězce na číslo za potenciální chybu. Je to proto, že řetězec ani číslo nemají mezi sebou dostatečné překrytí. Pro převod řetězce na číslo, postupujte takto:
/**
* nastav typ proměnné numString na unknown, jinak
* Typescript automaticky usoudí, že se jedná o řetězec
*/
let numString: unknown = "23452";
// Konverze typu pomocí as - numString je převeden na číslo
// a uložen do proměnné score
let score = numString as number;
console.log(score);
console.log(score * 35);
Výstup:
23452
820820
Z výstupu si můžeme všimnout, že proměnná numString
byla převedena na číslo a uložena do proměnné score
. Následně můžeme s proměnnou score
provádět matematické operace, například násobení, protože její hodnota je nyní číslo.
Typová aserce pomocí <>
Typová aserce pomocí <>
se rovněž dá použít pro převod řetězce na číslo. Funguje zcela identicky jako s použitím klíčového slova as
. Jediný rozdíl je v syntaxi, kterou vidíme níže:
let numString: unknown = "23452";
// Typová aserce pomocí <> pro konverzi řetězce na číslo
let score = <number>numString;
console.log(score);
console.log(score * 35);
Výstup:
23452
820820
Výstup je stejný jako při použití klíčového slova as
. Opět si pamatujte, že byste neměli používat typovou aserci pro převod řetězců, které neobsahují číselné hodnoty.
Použití konstruktoru Number
Pro převod řetězce na číslo pomocí konstruktoru Number
, předáte řetězec, který chcete převést, do konstruktoru Number
, jak ukazuje následující fragment kódu:
let numString = "23452"; // typ automaticky určen jako string
let lives: string = "20"; // typ definován jako string
// předání řetězce do konstruktoru Number pro převod na číslo
let score = Number(numString)
console.log(score / 17)
// předání řetězce do konstruktoru Number pro převod na číslo
let remainingLives = Number(lives);
console.log(remainingLives - 4)
Výstup:
1379.5294117647059
16
Při použití konstruktoru Number
není nutné nastavovat typ řetězce na unknown
. Funguje s řetězcovými hodnotami, u kterých byl typ odvozen nebo anotován jako řetězec. Nezapomeňte však, že je potřeba předat číselné řetězce, například „514“. Pokud předáte řetězec, který nelze převést na číslo, vrátí se NaN
(Not-a-Number).
Použití unárního operátoru plus (+)
Unární operátor plus (+), který předchází svému operandu, se vyhodnotí jako operand, kterému předchází. Například +2
se vyhodnotí jako číslo 2, +542
se vyhodnotí jako číslo 542 atd. Pokud však operand není číslo, unární operátor plus (+) se ho pokusí převést na číslo.
Například +"98"
se vyhodnotí jako 98
a +"0"
se vyhodnotí jako číslo 0
. Proto můžeme použít unární operátor plus (+) pro převod řetězců na čísla. Pokud předáte řetězec, který nelze převést na číslo, vrátí se NaN, jak ukazuje následující příklad:
let numString1 = "23452";
let numString2 = "973.82"
let word = "hello"
// Použití unárního plus (+) pro převod řetězců na čísla
let num1 = +numString1;
let num2 = +numString2;
let notNumber = +word;
console.log(`${num1} is a ${typeof num1}`);
console.log(`${num2} is a ${typeof num2}`);
console.log(notNumber);
Výstup:
23452 is a number
973.82 is a number
NaN
Použití unárního operátoru plus (+) je dobrý způsob pro převod řetězců na čísla, protože je rychlý a nevykonává žádné další operace s operandy.
Použití parseInt() a parseFloat()
Stejně jako JavaScript, ani TypeScript nerozlišuje mezi celými a desetinnými čísly (známými také jako čísla s plovoucí desetinnou čárkou). Všechna jsou považována za typ number
. To znamená, že chování parseInt()
a parseFloat()
se mírně liší.
parseInt()
přijímá řetězec jako argument, analyzuje ho a vrací jeho celočíselný ekvivalent podle zadaného radixu. parseFloat()
přijímá řetězec, analyzuje ho a vrací číslo s plovoucí desetinnou čárkou.
Pokud například předáte „897“ do parseInt()
i parseFloat()
, získáte zpět číslo 897. Pokud však předáte 897.75 do parseInt()
a parseFloat()
, parseInt()
vrátí 897, zatímco parseFloat()
vrátí 897,75.
Z toho vyplývá, že při převodu číselných řetězců, které nemají desetinné místo, použijte parseInt()
. Pokud však číselný řetězec desetinná místa obsahuje, použijte parseFloat()
, jak ukazuje následující kód:
let numString1 = "897.75";
let numString2 = "724";
let word = "hello";
console.log("Analýza číselných řetězců s desetinnými místy")
console.log(`Použití parseInt -> ${parseInt(numString1)}`);
console.log(`Použití parseFloat -> ${parseFloat(numString1)}`);
console.log("Analýza číselných řetězců celými čísly")
console.log(`Použití parseInt -> ${parseInt(numString2)}`);
console.log(`Použití parseFloat -> ${parseFloat(numString2)}`);
console.log("Analýza řetězců, které nelze převést na číslo")
console.log(parseInt(word));
console.log(parseFloat(word));
Výstup:
Analýza číselných řetězců s desetinnými místy
Použití parseInt -> 897
Použití parseFloat -> 897.75
Analýza číselných řetězců celými čísly
Použití parseInt -> 724
Použití parseFloat -> 724
Analýza řetězců, které nelze převést na číslo
NaN
NaN
Závěr
Při práci s řetězcovými hodnotami, například s výsledky z API, můžete mít potřebu je převést na čísla, abyste s nimi mohli provádět matematické výpočty. Když taková potřeba vyvstane, zvažte metody pro převod řetězců na čísla, které byly popsány v tomto článku.
Buďte však opatrní, protože při pokusu o převod řetězce na číslo se může objevit NaN (Not-a-Number).
Abyste se této chybě vyhnuli, ujistěte se, že všechny řetězce, které chcete převést na čísla, jsou skutečně číselné řetězce. Můžete také použít příkaz if
pro kontrolu výskytu NaN, abyste se vyhnuli chybám v kódu.
Dále můžete prozkoumat nejlepší knihovny a runtime pro TypeScript, abyste je jako vývojáři lépe poznali.