TypeScript
1.11.2020
TypeScript přidává do JavaScriptu typování, které nám pomáhá při vývoji odhalit různé chyby, na které
bychom jinak přišli až při běžícím programu a které se můžou špatně hledat. Zároveň funguje jako
transpilátor, u kterého si můžeme určit, jaká verze JavaScriptu (ECMAScriptu) se nám má vygenerovat.
JavaScript má relativně matoucí ekosystém a článek se věnuje přípravě projektu a naprogramování robota,
který nás, prostřednictvím vývojářské konzole, bude zdravit, dokud se mu nevybijí baterky. Protože jsme
na robota hodní, znovu ho nabijeme :-)
Slovníček
JavaScript | Jazyk podporovaný napříč webovými prohlížeči. Dnes je v něm možné programovat i mobilní nebo desktopové aplikace. Nemá nic společného s Javou :-) |
ECMAScript | JavaScriptový standard/specifikace, díky kterému kód správně funguje napříč prohlížeči. Dnešní JavaScript je tedy implementací ECMAScriptu. |
TypeScript | Jazyk, který rozšiřuje JavaScript a poté ho transpiluje do ECMAScriptu. |
Transpilátor | Kompilátor, který překládá jazyk do jiného jazyka. |
ES | Zkratka pro ECMAScript, která se může číslovat podle releasu. Například ES6 a ES2015 je totéž. |
Modul | V JavaScriptu je modul jakýkoliv soubor, který exportuje nějakou funkci nebo třídu. |
CDN | Content Delivery Network je cloudové úložiště souborů. |
Obsah
Příprava projektu
Vytvoříme složku Web a přesuneme se do nícd C:\Web
npm install --save-dev typescript
--save-dev atribut nám nainstaluje typescript do složky node_modules,
která se vytvoří v našem projektu. Spouštět node moduly můžeme pak příkazem npx.
Alternativou je nainstalovat typescript do počítače globálně, můžeme pak tsc
kompilátor pouštět rovnou.
Vytvoříme podsložku ts a v ní konfigurační soubor TypeScriptu tsconfig.json.
npm install -g typescript
{
"compilerOptions": {
"target":"es6",
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"strict": true
}
}
- "target":"es6" tsc transpiluje TypeScript do ES6, ten je podporovaný všemi prohlížeči mimo IE (ten je nahrazený Edgem).
- "module": "es6" chceme použít ES6 modul loader (způsob, jakým propojujeme TS soubory mezi sebou).
- "moduleResolution": "node" Způsob vyhledávání modulů, node volba je doporučená pro TypeScript.
- "sourceMap": true exportuje js.map soubory, díky kterým můžeme debugovat TypeScript přímo v prohlížeči.
- "outDir": "dist" složka do které se nám transpiluje TypeScript na ES, do této složky se pak musíme odkazovat z HTML.
- "strict": true striktnější kontrola kódu, vyžaduje používání typů.
Naprogramování robota
vytvoříme si třídu pro robota, který bude umět zdravit a dobíjet se. Každé pozdravení ho ale bude stát nějakou energii :-) Při inicializaci robota musíme uvést jeho jméno.export class Robot {
// private properties
private name: string;
private batteryCapacity: number;
private batteryMaxCapacity: number = 100;
// getters
get Name(){ return this.name; }
get BatteryCapacity(){ return this.batteryCapacity; }
get BatteryMaxCapacity(){ return this.batteryMaxCapacity; }
// setters
// set Name(value: string){ this.name = value; }
constructor(name: string) {
this.name = name;
this.batteryCapacity = this.batteryMaxCapacity;
}
charge() {
this.batteryCapacity = this.batteryMaxCapacity;
}
greet(): string {
const energyDrain: number = 40;
if (this.batteryCapacity < energyDrain){
throw new Error('Not enough battery capacity, please charge me.');
}
this.batteryCapacity = this.batteryCapacity - energyDrain;
return `Hello, my name is ${this.name}.`;
}
}
<html>
<body>
<button id="run-robot">Run robot !</button>
</body>
<script type="module">
import { Robot } from './ts/dist/Robot.js';
document
.getElementById("run-robot")
.addEventListener("click", function(){
let robot = new Robot('Robocop');
// Lets our robot greets us three times
for (var i = 1; i < 4; i++) {
try {
console.log(robot.greet());
console.log(`battery is loaded at ${ robot.BatteryCapacity }`)
} catch (error) {
console.log(`Greeting failed. ${ error.message }`)
}
}
// Charge the battery
console.log(`Charging robot.`)
robot.charge();
if (robot.BatteryCapacity == robot.BatteryMaxCapacity) {
// Robot is charged, lets greets again
console.log(robot.greet());
}
});
</script>
</html>
npx tsc
pokud bychom chtěli zkompilovat pouze jeden soubor,
tak se tsconfig.json ignoruje a musíme uvést konfigurační parametry zvlášť, například
npx tsc --target es6 robot.ts
Spuštění
Pokud otevřeme náš index.html ve webovém prohlížeči napřímo, tak dostaneme chybovou hlášku
access to script at 'file:///.../Web/ts/dist/Robot.js' from origin 'null' has been blocked by CORS policy
CORS policy zabraňuje import souborů mimo doménu.
Musíme tedy náš web nasadit na nějaký hosting. Pro jednoduchost použijeme doplňek do chromu Web Server for Chrome, který nám bude poskytovat statické soubory. Doplněk spustíme a jako root webu zvolíme naší složku Web. Nyní si můžeme otevřít náš web v prohlížeči a po kliknutí na tlačítko Run robot ! nás robot začne zdravit, ale po dvou pozdravech mu dojde energie, dobije se a pozdraví nás znova :-) Developerskou konzoli v prohlížeči otevřeme klávesou F12.
Import externí knihovny z CDN
Pokud bychom potřebovali v TypeScript kódu použít nějakou knihovnu, kterou stahujeme přes CDN poskytovatele, můžeme si stáhnout tzv. "declaration file", který má příponu d.ts. Jedná se v podstatě o interface k dané knihovně, který nám umožní používat intelliSense (napovídání a doplňování kódu). Jako příklad můžeme nainstalovat typování pro rozšířenou knihovnu jQuerynpm install @types/jquery --save-dev
/// <reference types="jquery" />
Alternativně můžeme
místo instalace typování a reference knihovny nadeklarovat proměnou let $: any;
(například pro jQuery, pokud by se nejednalo o globální knihovnu) a odkazovat se na ní.
Přijdeme tak sice o intelliSense, ale kód se zkompiluje.
knihovnu stáhneme přes CDN
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
/// <reference types="jquery" />
// When document is fully loaded
jQuery(function() {
// Notify user via alert box, that jquery is used
alert('jQuery is running from CDN and TypeScript')
// Set background color of the page to red
$('body').css('background-color', 'red')
});
<script type="module" src="./ts/dist/App.js"></script>