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

Podobne dokumenty