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
nainstalujeme do projektu TypeScript
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.
npm install -g typescript
Vytvoříme podsložku ts a v ní konfigurační soubor TypeScriptu tsconfig.json.
{
  "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}.`;
    }
}
vytvoříme si index.html, ve kterém bude tlačítko Run robot !, na které máme nastavený event a v ten moment nás robot začne zdravit.
<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>
Spustíme kompilátor z rootu našeho projektu
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 jQuery
npm install @types/jquery --save-dev
V TypeScriptu jí nalinkujeme jako globální knihovnu
/// <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>
vytvoříme TypeScript soubor App.ts, využívající jQuery knihovnu
/// <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')
});
naimportujeme TypeScript
<script type="module" src="./ts/dist/App.js"></script>
při otevření stránky se nám zobrazí alert box a stránka se obarví do červena :-), díky tomu víme, že knihovna se spustila v pořádku.

Odkazy