Wprowadzenie do TypeScript - Instytut Informatyki Teoretycznej i
Transkrypt
Wprowadzenie do TypeScript - Instytut Informatyki Teoretycznej i
Wprowadzenie do TypeScript Wprowadzenie do TypeScript Tworzenie serwisów Web 2.0 dr inż. Robert Perliński [email protected] Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 21 maja 2016 1/53 Plan prezentacji 1 TypeScript Wprowadzenie Szybki start Kompilacja Typy Klasy Funkcje 2 Źródła Wprowadzenie do TypeScript 2/53 JavaScript vs TypeScript vs Dart Zainteresowanie w wyszukiwaniu względem najwyższego punktu na wykresie Wprowadzenie do TypeScript 3/53 TypeScript https://www.typescriptlang.org/ Wsparcie dla najpopularniejszych edytorów: Instalacja: npm install -g typescript Kompilacja: tsc helloworld.ts Wprowadzenie do TypeScript 4/53 Dlaczego TypeScript zamiast JavaScript? Język JavaScript: oprócz licznych zalet posiada jednak kilka słabych stron, od samego początku nie był tworzony z myślą o dużych aplikacjach webowych, obecnie aplikacje oparte o JavaScript zawierają często ponad 50 tysięcy linii kodu. Powstanie TypeScript: z inicjatywy Microsoft w 2012 roku powstaje TypeScript, jedną z osób, które pracują nad nim jest Anders Hejlsberg, główny architekt języka C#, syntaktycznie (składniowo) jest on podobny do JScriptu. Wprowadzenie do TypeScript 5/53 Cechy języka TypeScript I Cechy języka TypeScript: jest nadzbiorem języka JavaScript, rozszerza składnie JavaScript o dodatkowe elementy, jakikolwiek program napisany w JavaScript będzie pracował z TypeScript bez najmniejszych zmian, kompiluje się do prostego JavaScript (ECMAScrit 3 albo nowszego), działa na każdej przeglądarce, na każdym urządzeniu, na każdym systemie operacyjnym. Wprowadzenie do TypeScript 6/53 TypeScript ES5 ma wsparcie 86.81% + 7.75% = 94.56% (http://caniuse.com/#search=es5) Wprowadzenie do TypeScript 7/53 Cechy języka TypeScript II Cechy języka TypeScript: darmowy, udostępniony jako open source (Apache License 2.0), zapewnia dostęp do najnowszych cech JavaScript, również tych z ECMAScript 2015 i propozycji na przyszłość: szablony klas i funkcji, wzorzec dekorator, ... obecnie TypeScript doczekał się wydania wersji 1.8, w której wprowadzono jeszcze więcej nowości i poprawek do istniejących rozwiązań, Angular 2 jest napisany w TypeScript, zob. LINK. Wprowadzenie do TypeScript 8/53 Co udostępnia TypeScript? TypeScript udostępnia: statyczne typy (boolean, number, string, tablice, krotki...), deklaracje zmiennych z let, const i var, interfejsy, funkcje, opcjonalne parametry, wyrażenia lambda, klasy z dziedziczeniem, szablony klas i funkcji, unie, symbole (zdefiniowane i tworzone przez użytkownika), iteratory i generatory, moduły i przestrzenie nazw, ... https://github.com/Microsoft/TypeScript/raw/master/doc/TypeScript% 20Language%20Specification.pdf Wprowadzenie do TypeScript 9/53 Szybki start - instalacja TypeScript można zainstalować na dwa sposoby: korzystając z npm (menadżer pakietów w Node.js): npm install -g typescript dodając plugin TypeScript do VisualStudio (w nowszych wersjach jest dodany domyślnie). Wprowadzenie do TypeScript 10/53 Szybki start - pierwszy program hello.ts function hello(osoba) { return "Witaj " + osoba; } var bob = "Robert Nowak"; document.body.innerHTML = hello(bob); Plik ma rozszerzenie *.ts ale to zwykły plik JavaScript Kompilacja: tsc hello.ts Otrzymujemy plik hello.js <!DOCTYPE html> <html> <head> <title>Witaj!</title> <meta charset="utf-8" /> </head> <body> <script src="hello.js"></script> </body> </html> Wprowadzenie do TypeScript 11/53 Szybki start - określenie typu, błędy kompilacji Kompilacja: tsc hello.ts hello.ts function hello(osoba: string) { return "Witaj " + osoba; } var bob = 12; //"Robert Nowak"; document.body.innerHTML = hello(bob); ### BŁEDY (ale plik JavaScript zostanie wygenerowany) hello.ts(7,33): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. var bob = [12, 13, 15]; hello.ts(7,33): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'. document.body.innerHTML = hello(); hello.ts(7,27): error TS2346: Supplied parameters do not match any signature of call target. Wprowadzenie do TypeScript 12/53 Szybki start - interfejsy hello.ts interface Osoba { imie: string; nazwisko: string; } function hello(osoba: Osoba) { return "Witaj " + osoba.imie + " " + osoba.nazwisko; } var bob = { imie: "Robert", nazwisko: "Nowak" }; document.body.innerHTML = hello(bob); Interfejs Osoba określa obiekt z dwoma polami: imie oraz nazwisko. Dwa typy są zgodne jeśli ich struktura wewnętrzna jest zgodna. hello.js function hello(osoba) { return "Witaj " + osoba.imie + " " + osoba.nazwisko; } var bob = { imie: "Robert", nazwisko: "Nowak" }; document.body.innerHTML = hello(bob); Wprowadzenie do TypeScript 13/53 Szybki start - klasy, błędy class Student { nazwa: string; constructor(public imie, public drugieImie, public nazwisko) { this.nazwa = imie + " " + drugieImie + " " + nazwisko; } } interface Osoba { imie: string; nazwisko: string; } function hello(osoba: Osoba) { return "Witaj " + osoba.imie + " " + osoba.nazwisko + " " + osoba.drugieImie; } var bob = new Student("Robert", "W.", "Nowak"); document.body.innerHTML = hello(bob); // Witaj Robert Nowak W. ### BŁEDY (ale plik JavaScript zostanie wygenerowany) hello.ts(14,63): error TS2339: Property 'drugieImie' does not exist on type 'Osoba'. Wprowadzenie do TypeScript 14/53 Kompilacja - opcje kompilatora tsc Wybrane opcje kompilatora tsc: --allowJs - pozwala na kompilację plików JS (domyślnie włączone), --init - inicjalizuje projekt TypeScript i tworzy plik tsconfig.json, -m KIND, --module KIND - określa sposób generowania kodu JS dla obsługi modułów; dostępne opcje: ’commonjs’, ’amd’, ’system’, ’umd’, ’es2015’. --moduleResolution - określa algorytm wczytywania modułów; dostępne opcje: ’node’ (domyślnie od wersji 1.6) i ’classic’, --outFile FILE - łączy wyjście kompilatora i zapisuje w jednym pliku, -p DIRECTORY, --project DIRECTORY kompiluje projekt w podanym katalogu, --rootDir LOCATION - określa główny katalog plików źródłowych, -t VERSION, --target VERSION określa wersję docelową ECMAScript: ’es3’ (domyślnie), ’es5 albo ’es6’, -v, --version - pokazuje wersję kompilatora, -w, --watch - tryb śledzenia plików, automat. rekompilacja przy zmianach, Wprowadzenie do TypeScript 15/53 Kompilacja - plik tsconfig.json Plik tsconfig.json: określa główne pliki projektu oraz opcje kompilatora wymagane w projekcie, wskazuje na główny katalog projektu TypeScript, jest ignorowany jeśli przy wywołaniu tsc podano konkretne pliki, może być całkowicie pusty - wszystko jest kompilowane z domyślnymi opcjami. Dwa sposoby na użycie tsconfig.json: uruchomienie polecenia tsc bez plików wejściowych - kompilator szuka pliku tsconfig.json w bieżącym katalogu, jeśli go nie znajdzie, to szuka w katalogach nadrzędnych, uruchomienie polecenia tsc bez plików wejściowych z opcją --project (albo -p); podany katalog powinien zawierać plik tsconfig.json. Wprowadzenie do TypeScript 16/53 Kompilacja - plik tsconfig.json Właściwość „files” nie może być jednocześnie z „exclude” - jedna albo druga „files” i „exclude” dotyczą kompilacji lub wyłączenia z niej plików *.ts i *.tsx tsconfig.json { "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": false, "outFile": "../../built/local/tsc.js" }, "files": [ /* kompiluje pliki wymienione na liście */ "hello.ts" "core.ts", "utilities.ts" ], "exclude": [ /* kompiluje wszystko poza zawartością tych katalogów */ "node_modules", "wwwroot" ] } Wprowadzenie do TypeScript 17/53 Kompilacja - dyrektywy kompilatora Dyrektywy potrójny-slash (ang. triple-slash directives): to pojedyńcze linie komentarza zawierające pojedyńczy znacznik XML, działają tylko u samej góry pliku, który je zawiera, mogą być poprzedzane tylko innymi dyrektywami, jeśli wystąpią poniżej jakiś instrukcji są zwykłym komentarzem, najczęstsza dyrektywa to /// <reference path="..." /> określa ona jakie dodatkowe pliki kompilator ma uwzględnić w kompilacji, inne przykłady: /// <reference no-default-lib="true"/> /// <amd-module /> /// <amd-dependency /> Wprowadzenie do TypeScript 18/53 Kompilacja - definicje do TypeScript https://github.com/typings/typings Typings pozwala na zarządzanie i instalacje definicji do języka TypeScript. Używa pliku typings.json, który może korzystać z rejestru typów, GitHuba, NPM, Bowera, HTTP, i plików lokalnych. Pakiety mogą używać definicji typów z różnych źródeł, w różnych wersjach, zapobiegając konfliktom. Instalacja: npm install -g typings Oficjalne repozytorium z definicjami do TypeScript: https://github.com/typings/registry/ Wprowadzenie do TypeScript 19/53 Kompilacja - DefinitelyTyped http://definitelytyped.org/ https://github.com/DefinitelyTyped/DefinitelyTyped Repozytorium blisko 1800 zbiorów definicji do języka TypeScript. Użycie (w pliku TypeScript, będzie komentarzem w pliku JavaScript): /// <reference path="jquery.d.ts" /> Wprowadzenie do TypeScript 20/53 Kompilacja - przykład z DefinitelyTyped Definicje typów dla Node.js: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/node Pobieramy do projektu odpowiednie definicje zależnie od wersji Node.js Dołączamy pobrany plik do wybranego pliku TypeScript Używamy funkcjonalności z Node.js: test2.ts /// <reference path="node-0.10.d.ts" /> const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Jak masz na imię? ', function(imie) { console.log('Witaj', imie); rl.close(); }); // declare function require(name:string); Wprowadzenie do TypeScript 21/53 Kompilacja - definicja typu do TypeScript Kompilator TypeScript (tsc) odnajduje, rozwiązuje zależności według specjalnego algorytmu. Potrafi także wczytywać definicje dołączone do pakietów NPM: w pliku package.json dołączanego pakietu, np.: { "name": "foo", "author": "Vandelay Industries", "version": "1.0.0", "main": "./lib/foo.js", "typings": "./lib/foo.d.ts" } w pliku index.d.ts dołączanego pakietu. Definicja typu w naszym własnym pakiecie do Node.js powinna: być plikiem z rozszerzeniem *.d.ts, być napisana jako zewnętrzny moduł, nie mieć referencji z potrójnym slashem (/// <reference ... />). Wprowadzenie do TypeScript 22/53 Podstawowe typy w TypeScript boolean - przechowuje wartości true/false: let zrobione:boolean = false; number - w TypeScript (tak samo jak w JavaScript) wszystkie liczby są zmiennopozycyjne; TypeScript uwzględnia też zapis binarny i ósemkowy literałów (zgodnie ze standardem ECMAScript 2015): let let let let decimal: number = 6; hex: number = 0xf00d; binary: number = 0b1010; octal: number = 0o744; string - dane tekstowe, umieszczone wewnątrz znaku " albo ’: var napis: string = "Dowlony napis"; let nazwa = 'Jan Kowalski'; Wprowadzenie do TypeScript 23/53 Podstawowe typy w TypeScript - string string - zmienne napisowe mogą być rozciągnięte na wiele linii i zawierać szablony z innymi zmiennymi, używamy do tego zanku ‘ (odwrotny apostrof, backquote, na klawiaturze pod tyldą): let liczba: number = 12; let nazwa: string = 'Jan Kowalski'; let calosc: string = ‘Moje imie to ${nazwa}. Mam ${liczba+2} lat‘; Wynik w Java Script var liczba = 12; var nazwa = 'Jan Kowalski'; var calosc = "Moje\nimie to " + nazwa + ".\n\nMam Wprowadzenie do TypeScript " + (liczba + 2) + " lat"; 24/53 Podstawowe typy w TypeScript - tablice tablice - są dwa sposoby zapisu tablic: podajemy typ elementu, po którym są [] (tablica określonego typu): let tab1: number[] = [1, 3, 9]; // wynik w JS var tab1 = [1, 3, 9]; z wykorzystaniem typów szablonowych: let tab2: Array<string> = ['Ala', 'Ela', 'Ola']; // wynik w JS var tab2 = ['Ala', 'Ela', 'Ola']; Wprowadzenie do TypeScript 25/53 Podstawowe typy w TypeScript - krotki krotki - pozwalają utworzyć tablicę z ustaloną liczbą elementów, każde pole krotki może być innego typu: let para: [number, string]; para = [12,'krzesło']; // para = ['krzesło',11]; // utworzenie // inicjalizacja // BŁAD kompilatora tsc // console.log(para[0].substr(1)); console.log(para[1].substr(1)); para[3] = 'wazon'; // para[3] = true; console.log(para); // // // // BŁĄD, 'number' nie ma metody 'substr' OK OK, krotka zawiera zmienną string BŁAD, krotka nie zawiera zmiennej boolean Wynik w Java Script var para; para = [12, 'krzesło']; console.log(para[1].substr(1)); para[3] = 'wazon'; console.log(para); Wprowadzenie do TypeScript // inicjalizacja // "rzesło" // [ 12, 'krzesło', , 'wazon' ] 26/53 Podstawowe typy w TypeScript - typ wyliczeniowy enum - typ wyliczeniowy, pozwala nadawać bardziej przyjazne nazwy zbiorom wartości numerycznych, domyślnie numeracja zaczyna się od 0: enum Color {Red, Green, Blue} // enum Color {Red=2, Green, Blue} // enum Color {Red=2, Green=4, Blue=0} let kol: Color = Color.Green; // rozpoczynanie numeracji od 2 // dowolna numeracja let colorName: string = Color[2]; alert(colorName); // odwołanie po wartości numerycznej // wyświetla Blue Wynik w Java Script var Color; (function (Color) { Color[Color["Red"] = 0] = "Red"; Color[Color["Green"] = 1] = "Green"; Color[Color["Blue"] = 2] = "Blue"; })(Color || (Color = {})); var kol = Color.Green; Wprowadzenie do TypeScript 27/53 Podstawowe typy w TypeScript - „dowolny” typ any - określa typ zmiennej, który nie jest określony w trakcie jej tworzenia, zawartość zmiennej jest dynamiczna, kompilator dopuszcza różne wartości: let dowolna: any = 4; dowolna = 'Jan Kowalski'; dowolna = false; dowolna.ifItExists(); // na typie any można wywoływać różne metody dowolna.toFixed(); Typ any przydaje się również w tablicach o mieszanych wartościach: let tab: any[] = [1,'dwa', true]; tab[0] = 12; Wprowadzenie do TypeScript 28/53 Podstawowe typy w TypeScript - typ void void - określa brak jakiegokolwiek typu, wykorzystywany przy wartości zwracanych przez funkcje: function uwaga(): void { alert("Tutaj jest ostrzeżenie"); } Określenie zmiennej jako void jest nieużyteczne, pozwala na przypisanie jej tylko undefined albo null: let zmienna1: void = null; let zmienna2: void = undefined; // let zmienna3: void = 123; Wprowadzenie do TypeScript // BŁĄD 29/53 Podstawowe typy w TypeScript - określanie typu Są przypadki, w których samodzielnie określiamy typ zmiennej. Są na to dwa sposoby: podajemy typ zmiennej w nawiasach ostrokątnych: let liczba2: any = "12"; let napis3: number = (<string>liczba2).length; używamy słowa as: let liczba2: any = "12"; let napis3: number = (liczba2 as string).length; Wprowadzenie do TypeScript 30/53 Klasy w TypeScript Tradycyjny język JavaScript nie obsługuje programowania obiektowego, klas i dziedziczenia. Do języka JavaScript wprowadza pojęcie klas wprowadza dopiero ECMAScript 2015 (EcmaScript 6). Korzystając z TypeScript można korzystać z obiektowości już dzisiaj kompilacja wykonuje się do dowolnej wersji JavaScript. class Przywitanie { wiadomosc: string; constructor(wiadomosc: string) { this.wiadomosc = wiadomosc; // this wskazuje na pola składowe klasy } przywitanie() { return "Witaj, " + this.wiadomosc; } } let witaj = new Przywitanie(" piękną mamy wiosnę, prawda?"); alert(witaj.przywitanie()); Wprowadzenie do TypeScript 31/53 Dziedziczenie w TypeScript class Zwierze { // 1. extends nazwa: string; // 2. super constructor(nazwa: string) { // 3. przeładowywanie metod this.nazwa = nazwa; // 4. polimorfizm... } przemiesc(odleglosc: number = 0) { console.log(‘${this.nazwa} przemieścił się o ${odleglosc} m.‘) } } let zw1 = new Zwierze("ślimak Stefan"); zw1.przemiesc(0.5); // ślimak Stefan przemieścił się o 0.5 m. class Slimak extends Zwierze { constructor(nazwa: string) {super(nazwa);} // wyw. konstruktora z kl. bazowej przemiesc(odleglosc = 0.03) { // przeładowanie metody console.log('Pełzam ...'); super.przemiesc(odleglosc); } } let slimak1 = new Slimak("Marian"); let slimak2: Zwierze = new Slimak("Stefan"); slimak1.przemiesc(2); // Pełzam ... Marian przemieścił się o 2 m. slimak2.przemiesc(1.2); // wyw. metody z kl. pochodnej: Pełzam ... Stefan... Wprowadzenie do TypeScript 32/53 Dziedziczenie z TypeScript przeniesione na JavaScript var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Zwierze = (function () { function Zwierze(nazwa) { this.nazwa = nazwa; } Zwierze.prototype.przemiesc = function (odleglosc) { if (odleglosc === void 0) { odleglosc = 0; } console.log(this.nazwa + " przemie\u015Bci\u0142 si\u0119 o " + odleglosc + " m."); }; return Zwierze; }()); var zw1 = new Zwierze("ślimak Stefan"); zw1.przemiesc(0.5); var Slimak = (function (_super) { __extends(Slimak, _super); function Slimak(nazwa) { _super.call(this, nazwa); } Slimak.prototype.przemiesc = function (odleglosc) { if (odleglosc === void 0) { odleglosc = 0.03; } console.log('Pełzam ...'); _super.prototype.przemiesc.call(this, odleglosc); }; return Slimak; }(Zwierze)); var slimak1 = new Slimak("Marian"); var slimak2 = new Slimak("Stefan"); slimak1.przemiesc(2); slimak2.przemiesc(1.2); Wprowadzenie do TypeScript 33/53 Klasy w TypeScript - prawa dostępu W TypeScript: Domyślnie wszystkie składowe są publiczne (public). private oraz protected towrzy składowe prywatne i chronione. Składowe prywatne są dostępne tylko w danej klasie. Składowe chronione są dostępne w danej klasie i w pochodnych. Dwa typy są takie same jeśli odpowiednie pola wszystkich składowych są takie same. Jeśli klasy zawierają składowe prywatne lub chronione to będą takie same przy porównaniu tylko jeśli odpowiednie składowe prywatne lub chronione będą wspólne. Można tworzyć statyczne pola - słowo kluczowe static. Można tworzyć klasy abstrakcyjne: abstract class Zwierze { ... } ... Wprowadzenie do TypeScript 34/53 Klasy w TypeScript - prawa dostępu class Zwierze { private nazwa: string; protected masa: number; constructor(nazwa: string, masa: number) { this.nazwa = nazwa; this.masa = masa; } przemiesc(odleglosc: number = 0) { console.log(‘${this.nazwa} przemieścił się o ${odleglosc} m.‘) } } class Slimak extends Zwierze { constructor(nazwa: string, masa:number) { super(nazwa, masa); } przemiesc(odleglosc = 0.03) { // this.nazwa = 'Wojtek'; // BŁAD, pole prywatne this.masa = 12.34; // OK console.log('Pełzam ...'); super.przemiesc(odleglosc); } } let slimak1 = new Slimak("Marian", 0.34); // slimak1.nazwa = "Tomasz"; // BŁAD, pole prywante // slimak1.masa = 0.29; // BŁAD, pole chronione Wprowadzenie do TypeScript 35/53 Klasy w TypeScript - skrócony zapis konstruktora Poprzedzenie parametru konstruktora prawem dostępu (private, protected, public) tworzy pole klasy i od razu je inicjalizuje. Obie klasy w JavaScript wyglądają dokładnie tak samo. class Klasa1 { private pole1: string; constructor(pole1: string) { this.pole1 = pole1; } info() { console.log(this.pole1); } } class Klasa2 { constructor(private pole2: string) { } info() { console.log(this.pole2); } } let kl1 = new Klasa1('klasa 1'); let kl2 = new Klasa2('klasa 2'); kl1.info(); kl2.info(); // klasa 1 // klasa 2 Wprowadzenie do TypeScript 36/53 Klasy w TypeScript - metody set i get TypeScript wspiera metody dostępowe jako ograniczenie bezpośredniego dostępu do pól klasy. Są dostępne jednak dopiero dla standardu ECMAScript 5. Przykład dowolnego dostępu do składowej: class Moja { nazwa: string; } let moja = new Moja(); moja.nazwa = 'Moja ulubiona'; if(moja.nazwa) { console.log(moja.nazwa); } Wprowadzenie do TypeScript 37/53 Klasy w TypeScript - metody set i get Ta sama klasa z ograniczonym dostępem (metody set i teg): let haslo: string = 'tajne haslo'; // = 'moje haslo'; class Moja { private _nazwa: string; get nazwa(): string { return this._nazwa; } set nazwa(nazwa: string) { if(haslo && haslo=='tajne haslo') { this._nazwa=nazwa; } else { console.log('Brak dostępu'); } } } let moja = new Moja(); moja.nazwa = 'Moja ulubiona'; if(moja.nazwa) { console.log(moja.nazwa); } Wprowadzenie do TypeScript // // // // dokładnie jeden parametr Brak dostępu ALBO Moja ulubiona 38/53 Funkcje w TypeScript - nazwane i anonimowe Funkcje są kluczowe w JavaScript (wykorzystywane do tworzenia warstwy abstrakcji, udawania klas, przechowywania informacji, tworzenia modułów). Funkcje w TypeScript mają różnież znaczenie kluczowe. funkcje nazwane, anonimowe, wyrażenia lambda: // funkcja nazwana, można jej użyć gdziekolwiek chcemy function dodaj(x, y) { return x + y; } // funkcja anonimowa let mojeDodaj = function(x, y) { return x+y; }; // wyrażenia lambda let mojeDodaj2 = (x,y) => { return x+y; } let mojeDodaj3 = (x,y) => x+y; console.log(dodaj(12,23)); console.log(mojeDodaj(12,23)); console.log(mojeDodaj2(12,23)); console.log(mojeDodaj3(12,23)); Wprowadzenie do TypeScript 39/53 Funkcje w TypeScript - wyrażenia lambda Wyrażenia lambda (=>, fat arrow): mają jeszcze zwięźlejszy zapis niż funkcje anonimowe, => zastępuje słowo function, używane najczęściej do zapisu wywołań zwrotnych, w JS dopiero w standardzie ECMAScript 6, działa w TypeScript, nie ma problemu z zakresem słowa kluczowego this, składnia: (par1, par2, ..., parN) => { instrukcje } (par1, par2, ..., parN) => wyrażenie // równoważne z : => { return wyrażenie; } // Nawiasy są opcjonalne jeśli jest tylko jeden parametr: (jedenPar) => { instrukcje } jedenPar => { instrukcje } // Funkcja bez parametrów wymaga nawiasów () => { instrukcje } Wprowadzenie do TypeScript 40/53 Funkcje w TypeScript - wyrażenia lambda, przykłady let showName1 = () => {console.log("name: ")}; let showName2 = (name) => {console.log("name: "+name)}; let showName3 = name => console.log("name: "+name); showName1(); showName2('Ela'); showName3('Ela 22'); // name: // name: Ela // name: Ela 22 let a = [ "autobus", "rower", "motocykl", "odrzutowiec" ]; // Metoda map() tworzy nową tablicę z wynikami wywołanej funkcji // dla każdego elementu w tablicy, na rzecz której ją wywołano. let a2 = a.map( function(s){ return s.length } ); let a3 = a.map( s => s.length ); console.log(a2); console.log(a3); Wprowadzenie do TypeScript // [ 7, 5, 8, 11 ] // [ 7, 5, 8, 11 ] 41/53 Funkcje w TypeScript - wyrażenia lambda, przykłady II var simple = a => a > 15 ? 15 : a; simple(16); // 15 simple(10); // 10 let max = (a, b) => a > b ? a : b; // Łatwe działania na tablicach: filtrowanie, sumowanie, mapowanie, ... var var var var arr = [5, 6, 13, 0, 1, 18, 23]; sum = arr.reduce((a, b) => a + b); // 66 even = arr.filter(v => v % 2 == 0); // [6, 0, 18] double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] // Bardziej zwięzły zapis obsługi obietnic promise.then(a => { // ... }).then(b => { // ... }) Wprowadzenie do TypeScript 42/53 Moduły w TypeScript W TypeScript od wersji 1.5 (tak samo jak w ES2015) możemy mówić o: przestrzeniach nazw (dawniej moduły wewnętrzne), namespace Figury { ... } modułach (dawniej moduły zewnętrzne). Moduł to każdy plik zawierający instrukcję import albo export. Moduły mają: własny zakres, zasięg zmiennych, nie zanieczyszczają przestrzeni globalnej, wszystko co jest wewnątrz modułu, domyślne jest widoczne tylko w tym module, widoczność na zewnątrz wymaga użycia słowa export, wykorzystanie eksportowanych elementów wymaga instrukcji import. Wprowadzenie do TypeScript 43/53 Wczytywanie modułów Zależności pomiędzy modułami określamy wewnątrz nich poprzez import i export, Importowanie modułów odbywa się z użyciem narzędzia do wczytywania modułów (ang. module loader), Dobrze znane narzędzia wczytywania modułów z JavaScript to: CommonJS z Node.js, require.js dla aplikacji internetowych. Zależnie o wybaranego systemu do wczytywania modułów: CommonJS, require.js (AMD), SystemJS, system natywny z ES6, TypeScrit wygeneruje właściwy kod dla wybranego narzędzia. Różne narzędzia - różne kody wynikowe. Wprowadzenie do TypeScript 44/53 Eksportowanie modułów Dwa sposoby na eksportowanie elementów modułu: eksport deklaracji, export przed nazwą klasy, funkcji, ... eksport w osobnej instrukcji, pod koniec modułu. kolo.ts export const PI = 3.14159; // export przed nazwą klasy, czyli export deklaracji: export class Kolo { constructor(private r:number) { } pole():number { return this.r * this.r * PI; } } function poleKola(r:number): number { return r*r*3.14; } export {poleKola, PI as liczbaPI}; export {Kolo as Kolo2}; Wprowadzenie do TypeScript 45/53 Eksportowanie - kod w JavaScript Kod wynikowy dla systemu CommonJS czyli dla Node.js: kolo.js "use strict"; exports.PI = 3.14159; exports.liczbaPI = exports.PI; // export przed nazwą klasy, czyli export deklaracji: var Kolo = (function () { function Kolo(r) { this.r = r; } Kolo.prototype.pole = function () { return this.r * this.r * exports.PI; }; return Kolo; }()); exports.Kolo = Kolo; exports.Kolo2 = Kolo; function poleKola(r) { return r * r * 3.14; } exports.poleKola = poleKola; Wprowadzenie do TypeScript 46/53 Importowanie modułów Importowanie wybranych elementów albo całego modułu: geometria1.ts import {Kolo,Kolo2,PI} from './kolo'; import {poleKola, liczbaPI as PI2} from './kolo'; // import całego modułu do zmiennej import * as K from './kolo'; let k = new Kolo(2); let k2 = new Kolo2(3); console.log(PI); console.log(PI2); console.log(k.pole()); console.log(k2.pole()); console.log(poleKola(3)); // // // // // let k3 = new K.Kolo(1); console.log(k3.pole()); console.log(K.poleKola(1)); console.log(K.liczbaPI); // 3.14159 // 3.14 // 3.14159 Wprowadzenie do TypeScript 3.14159 3.14159 12.56636 28.27431 28.26 47/53 Importowanie - kod w JavaScript Kod wynikowy dla systemu CommonJS czyli dla Node.js: geometria1.js "use strict"; var kolo_1 = require('./kolo'); var kolo_2 = require('./kolo'); // import całego modułu do zmiennej var K = require('./kolo'); var k = new kolo_1.Kolo(2); var k2 = new kolo_1.Kolo2(3); var k3 = new K.Kolo(1); console.log(kolo_1.PI); console.log(kolo_2.liczbaPI); console.log(k.pole()); console.log(k2.pole()); console.log(kolo_2.poleKola(3)); console.log(k3.pole()); console.log(K.poleKola(1)); console.log(K.liczbaPI); Wprowadzenie do TypeScript 48/53 Domyślny export Każdy moduł może posiadać dokładnie jeden domyślny eksport (zapisujemy export default). kwadrat.ts export default 2.71828183; // export const liczbaE = 2.71828183; // export default function (a:number): number { export function poleKwadratu(a:number): number { return a*a; } // export default class Kwadrat { export class Kwadrat { constructor(private a:number) { this.a=a; } pole():number { return this.a * this.a } } Wprowadzenie do TypeScript 49/53 Importowanie elementów z domyślnym eksportem Domyślnie eksportowane elementy importujemy trochę innym zapisem. geometria2.ts import MATH_E from "./kwadrat"; import {Kwadrat,poleKwadratu} from "./kwadrat"; // import polKw from "./kwadrat"; // import {Kwadrat,liczbaE} from "./kwadrat"; // import Kwadrat from "./kwadrat"; // import {poleKwadratu,liczbaE} from "./kwadrat"; console.log(MATH_E); // default // console.log(liczbaE); // console.log(polKw(4)); // default console.log(poleKwadratu(3)); let kw = new Kwadrat(5); console.log(kw.pole()); Wprowadzenie do TypeScript 50/53 Ponowny, rozszerzony eksport Często moduły rozszerzają inne moduły. Mogą one częściowo odsłaniać to co było w modułach bazowych. Ponowny eksport (re-export) nie wymaga importowania czy deklarowania jakiś zmiennych. prostokat.ts export class Prostokat { constructor(private a:number, private b:number) { this.a=a; this.b=b; } pole():number { return this.a * this.b } } export {Kwadrat as Kwadrat2} from './kwadrat'; figury.ts export default 3; // liczbaFigur export * from './kolo'; export * from './prostokat'; Wprowadzenie do TypeScript 51/53 Ponowny, rozszerzony eksport II Wykorzystanie wcześniejszych modułów: geometria3.ts import {Prostokat,Kwadrat2} from "./prostokat"; let kw = new Kwadrat2(2.1); let pr = new Prostokat(2,7); console.log(kw.pole()); console.log(pr.pole()); import * as F from "./figury"; import {Kolo} from "./figury"; let k1 = new Kolo(4); console.log(k1.pole()); let pr2 = new F.Prostokat(3,4); console.log(F.PI); console.log(F.liczbaPI); console.log(F.poleKola(3)); // console.log(F.poleKwadratu(2,3)); // BŁAD, nie ma bo ... console.log(pr2.pole()); Wprowadzenie do TypeScript 52/53 Źródła https://angular.io/ https://pl.wikipedia.org/wiki/TypeScript https://www.typescriptlang.org/ http://codeguru.geekclub.pl/baza-wiedzy/ wprowadzenie-do-programowania-w-typescript-wstep,3575 https://developer.mozilla.org/en-US/docs/Web/JavaScript/ Reference/Functions/Arrow_functions https://blogs.msdn.microsoft.com/typescript/2015/03/05/ angular-2-built-on-typescript/ Wprowadzenie do TypeScript 53/53