Pokud to někdo s vývojem v javascriptu myslí vážně, měl by hledat způsob, jak nejlépe napsat udržitelný kód.
Díky vlastnostem, které přinesly ES5 a ES6, máme již k dispozici jazyk, který se netváří tak nepřátelsky.
Nicméně, stále existuje jedna věc, kterou javascript nenabízí a která je u většího projektu dost zásadní. Tou vlastností je typovost.
Proč bychom měli chtít typy v javascriptu?
Odpověď je vcelku jednoduchá. Z důvodu udržitelnosti kódu.
Představte si situaci, že máte projekt, kde chcete provést refactoring či změnu v modelu aplikace. V případě, že váš projekt nemá typy, budete se muset spolehnout pouze na špičkově napsané testy, které vám prozradí, zda jste v kódu něco nerozbili :)
Pojďme si udělat malou ukázku.
Máme entitu uživatele, kterou zobrazujeme v tabulce. Zjednodušený kód by vypadal asi následovně:
const users = [ {id: 1, firstName: 'Ales', lastName: 'Dostal', roles: ['admin']}, {id: 2, firstName: 'Petr', lastName: 'Novotny', roles: ['operator']}, ];
Nyní toto pole zobrazíme v tabulce:
users.map((row) => ( <tr> <td>{row.firstName} {row.lastName}</td> <td>{row.roles.join(', ')}</td> </tr> ));
Tady je svět asi v pořádku, ale co nastane, když budete potřebovat provést změnu, která spočívá v tom, že atribut roles budete muset zahodit a říci, že uživatel může obsahovat pouze jednu roli? Atribut roles se přejmenuje na role a přijímat bude pouze jeden řetězec, ale nikoli pole.
const users = [ {id: 1, firstName: 'Ales', lastName: 'Dostal', role: 'admin'}, {id: 2, firstName: 'Petr', lastName: 'Novotny', role: 'operator'}, ];
Co zbytek vašeho kódu?
Jen velice těžko budete dohledávat, zda objekt user obsahuje ty správné atributy, se kterými pracujete v metodě map, pro vypsání řádku tabulky. Javascript se bude tvářit, že je vše v pořádku a problém zjistíte až za běhu. A to skutečně nechce přeci nikdo.
Pojdmě náš kód obohatit o typovost pomocí Typescriptu. První věcí, kterou musíme udělat je, že si vytvoříme definici typu User.
interface User { readonly id: number; readonly firstName: string; readonly lastName: string; readonly roles: string[]; }
Nyní řekneme, že proměná users je typu pole User.
const users: User[] = [ {id: 1, firstName: 'Ales', lastName: 'Dostal', roles: ['admin']}, {id: 2, firstName: 'Petr', lastName: 'Novotny', roles: ['operator']}, ];
A nyní, když budeme chtít změnit model, změníme definici.
interface User { readonly id: number; readonly firstName: string; readonly lastName: string; readonly role: string; }
V té chvíli nám bude kompilátor Typescriptu vracet chybové hlášení, které nás upozorní, že máme špatně inicializovanou proměnou users a současně, že v metodě map předpokládáme, že existuje atribut roles, které je pole.
Teď si vemte tuto malou ukázku a vynásobte jí třeba 100x krát. Opravdu chcete ještě stavět projekt bez typů?
Co je tedy ten Typescript?
Typescript je jazyk, který byl představen v roce 2012 Microsoftem. V podstatě vychází z jednoduché myšlenky, která říká: "Pište klasicky v javascriptu, jen k němu přidejte typy".
I když Typescript má i další vlastnosti, které javascript nenabízí, tak jeho hlavní přínos je právě v oné přidané typovosti.
V praxi to vypadá tak, že píšete soubor, který si označíte jako typescript soubor (většinou pomocí přípony *.ts) a poté tento soubor zkompilujete kompilátorem Typescriptu. Výsledkem je javascriptový soubor, který je v dané ES specifikaci. O tom, do jaké specifikace chcete soubor kompilovat je na vás.
Více se o typescriptu můžete dozvědět z oficiálního webu.
Typescript není Java
Často se setkávám s tím, že lidé k Typescriptu přistupují jako k Jave. I když zde najdete spoustu společných vlastností, je dobré mít stále na paměti, že Typescript funguje jinak.
Jedním z hlavních rozdílů je to, že Typescript své typy porovnává na úrovni struktury.
Uveďme si příklad:
interface Cat { name: string; } interface Dog { name: string; } const cat: Cat = {name: 'Mourek'}; const dog: Dog = cat;
Proč tomu tak je?
Jde o to, že Typescript sice má typy, ale představte si, že jsou to stejně jen jakési flagy, které Vám mají pomáhat při psaní kódu. Poté, co se daný soubor zkompiluje do javascriptu, tak typy jsou odstraněny a pracuje se pouze s JSONem.Další věcí je, že chyby, které Vám kompilátor Typescriptu bude hlásit můžete často ignorovat. Výsledný kód bude funkční, dokud…
Příkladem je také třeba klíčové slovo readonly, kterým pokud označíte atributy daného typu, tak tím říkáte, že je nelze přímo přepsat. Nicméně, pokud to v kódu ignorujete, tak výsledkem bude validní javascript, protože ten žádné klíčové slovo readonly nezná.
Proto budťe obezřetní, při psaní v Typescriptu. Pořád je třeba mít na paměti, že je to javascript, který si jen typuji.
Další možnosti, jak typovat javascript
Kromě Typescriptu zde existuje ještě jedna varianta, která ve své podstatě dělá to samé (i když jiným způsobem). Tou variantou je FlowType či označováno jen jako Flow.
Flow je statická typová kontrola, kterou vytvořili lidé z facebooku. Na rozdíl od Typescriptu, je Flow méně invazivní a jedná se v podstatě pouze o "type check", kdežto v případě Typescriptu to je kompletní kompilace.
A proč tedy Typescript a ne Flow?
Tuto otázku jsem si pokládal dost často. Přeci jen, vždy máme touhy pokukovat po alternativách a hledat, zda někdo nemá ten "trávníček o něco zelenější". Já osobně jsem do Typescriptu šel ze dvou hlavních důvodů.
1. Typescript je tady déle a používá ho více knihoven
Tím, že byl první, tak z toho dodnes těží. Týká se to zejména knihoven, které když stáhnete z NPM, často se setkáte s problémem, že daná knihovna nemá definované typy. A pokud ano, je větší pravděpodobnost, že typy budou pro Typescript, nikoli pro Flow.
2. Angular 2
Ač jsem zastánce Reactu a Angular vnímám spíše jako ukázkovou cestu, kterou nejít, dá se zde mluvit o tom, že Typescript je nejvíce zpopularizován právě Angularem 2, který tento jazyk zvolil jako výchozí. Microsoft vytvoří jazyk a Google framework, který ho evangelizuje. Ironie, že? :)
Závěr
Už jste začali používat typy v javascriptu? :)
Žádné komentáře:
Okomentovat