1
Software Factory Web Mobile DevOps Labs Formazione 2
google cloud platform Le tecnologie
google cloud platform redis 3
Learning Factory Training Eventi Talks 4
Chi Sono? Developer per scelta e per passione, amante di nerdaggini di ogni tipo ed amante della condivisione del sapere! 5 . 1
TypeScript oh no, un altro xyzScript! 6
TypeScript Javascript che scala o semplicemente... JS con i types! 7
Breve Storia 2010 - Microsoft inizia lo sviluppo 2012 - Prima Release supportata da Visual Studio 2013 - Supporto ad altri IDE 2014 - TypeScript 1.0 2015 - AtScript viene implementato interamente in TypeScript 2017 - Standard de facto per un Javascript solido! 8
TypeScript è un superset di Javascript 9
Ricordiamo che... ...per usare ES6 (e successivi) è richiesto l'uso di transpiler/compiler: Babel, Traceur, Typescript compiler, ... Tabella di compatibilità 10
Transpiler TypeScript https://www.typescriptlang.org/ Babel https://babeljs.io/ 11
Javascript + Types JS + ES6/ES7/... + Types Compatibile con JS standard Genera codice JS standard Supporto OOP Implementazione Moduli Compile Time Errors Pensato per Applicazioni Scalabili Solid Development Experience Supporto dei Code Editor Supporto dei Tools (Webpack, Gulp, Grunt, etc...) Colma il GAP di Compatibilità e Produttività 12
...e se lo dice Anders Hejlsberg... 01:00:36 13
Strumenti di Lavoro Fondamentali npm tsc editor/IDE oppure usare per rapide proveTS Playground 14
Preparare un ambiente di sviluppo essenziale Installare Node (npm) Installare Pacchetti typescript/lite-server come dipendenze di sviluppo Configurazione package.json Configurazione tsconfig.json Creazione Progetto Base (index.html, app.ts) 15
Creazione di un Environment npm init --yes npm install --save-dev typescript lite-server tsc --init // Configura tsconfig ("outDir": "./dist") // Crea index.html // Crea app.ts // Configura package.json: (script: "start": "lite-server & tsc --watch") 16
Types In Typescript è possibile definire il tipo di variabili, parametri o valori di ritorno. 17 . 1
Staticamente tipizzati vs Dinamicamente tipizzati “Quando io vedo un uccello che cammina come un’anatra, nuota come un’anatra e starnazza come un’anatra, io chiamo quell’uccello 'anatra'”. Whitcomb Riley 17 . 2
Types Immediato Feedback in Sviluppo Autocomplete e Code-Suggestion contestualizzato Completamente Opzionale Configurazione tsconfig.json 17 . 3
Types Boolean Number String Array Tuple Enum Object Any Void Null/Undefined Never 17 . 4
Types Type assertion Inference Type compatibility Type Guard 17 . 5
Type definition let myName = "Francesco"; let otherName: string = "Aurelio"; let num: number = 2; //questo non verrà compilato! num = "test"; let arr: Array<number> = [1, 2, 3, 4]; let arr2: string[] = ["one", "two"]; 17 . 6
Type definition let addNumbers = (num1: number, num2: number): number => { return num1 + num2; }; let parseString : (input: string) => string; parseString = (input: string) => "un risultato qualunque"; //questo verrà compilato! addNumbers("2", 4); 17 . 7
Type definition //Tuples let tuple : [string, number]; tuple = ["devil", 666]; tuple[0]; tuple[1]; //enums enum Color {Red, Green, Blue}; let c: Color = Color.Red; if (c === Color.Red) { //farai qualcosa qui... } 17 . 8
Types (ES6) Scopes delle Variabili Destrutturazione Spread / Rest String Literal 17 . 9
Scope delle Variabili var foo; //functional scope let bar; //block scope const baz = "un valore"; //riferimento in sola lettura const value = 2; value = 1; //errato const obj = { name: "Aurelio" }; obj = {}; //errato obj.name = "Francesco"; //ok 17 . 10
Destrutturazione //Arrays e Tuples let [firsts, second, third] = [1, 2, 3]; console.log(firsts); // 1 console.log(second); // 2 console.log(third); // 3 //objects let {a, b} = { a: "test1", b: "test2" }; let { a: betterName1, b: betterName2 } = { a: "test1", b: "test2" }; //Spread / Rest let arr: number[] = [1, 2]; let concat = [...arr, 3, 4]; let [a, b, ...rest] = concat; 17 . 11
Template Literals //Template Literals let oldString = 'Una stringa'; let moderString = `Ancora una stringa`; let multilineString = `Questa invece è una stringa multilinea`; //Per i fan degli Iron Maiden let number = 666; let who = 'Beast'; let oldString = number + ' the number of the ' + who; let newString = `${number} the number of the ${who}`; 17 . 12
Definizione di Funzioni let fun = (param: number): string => { return "string"; }; //parametri opzionali let fun = (arg1: number, arg2?: number) => { //... } //rest let fun2 = (arg1: number, ...restOfArgs: number[]) => { //... }; //valore di default let fun2 = (arg1 = 0) => { // 17 . 13
Interfacce In Typescript sono i contratti, che ogni classe (e non solo) che implementa l'interfaccia deve soddisfare. 18 . 1
Interfacce Descrivono oggetti Definiscono contratto/protocollo Usate solo in fase di compilazione Molto Flessibili (proprietà dichiarate, opzionali, metodi, etc...) Ereditabili Molto simili alle interfacce Java/C# 18 . 2
Interfacce //Senza Intefaccia function printLabel(labelledObj: { label: string }) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj); //Con Intefaccia interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; i tL b l( Obj) 18 . 3
Interfacce per Oggetti interface User { name: string; surname: string; age?: number; } let me: User = { name: 'Francesco', surname: 'Sciuti', age: 30 // mi piacerebbe tanto }; //questa operazione non è consentita: me.something = 123; 18 . 4
Interfacce per Oggetti interface Point { readonly x: number; readonly y: number; } let p1: Point = { x: 10, y: 20 }; p1.x = 5; // errore! 18 . 5
Interfacce per Funzioni interface searchFunc { (query: string, source: string) : boolean } let mySearch : searchFunc = (q: string, s: string) => { return true; } 18 . 6
Classi Se ES6 introduce le classi in JS, TypeScript le rende migliori! 19 . 1
Classi Caratteristiche delle classi ES6 Sintassi e Leggibilità Migliorata Supporto ad Interfacce (Multiple) Modificatori d'Accesso (public, protected, private) Proprietà Statiche Overload di Metodi e Costruttori Ereditabili Classi Astratte 19 . 2
Classi //Classe class SayHi { toWho: string; constructor(toWho: string) { this.toWho= toWho; } hi() { return "Hello, " + this.toWho; } } let hi = new SayHi("Francesco"); 19 . 3
Proprietà class Person { static someStaticAttr = 2; private _id: number; constructor(public name: string, public secondName: string, public age: number) { } } 19 . 4
Getters and Setters class Person { //... get fullName():string { return `${this.name} ${this.secondName}`; } set fullName(value:string) { //some parsing probably this.name = valueOfName; this.secondName = valueOfSecondName; } } 19 . 5
Ereditarietà class Person { protected name: string; constructor(name: string) { this.name = name; } } class Employee extends Person { private department: string; constructor(name: string, department: string) { super(name); this.department = department; } public sayHi() { return `Ciao, mi chiamo ${this.name}, lavoro a ${this.department}.`; } } 19 . 6
Implementazione di Interfacce interface ClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; } constructor(h: number, m: number) { } } 19 . 7
Proprietà Statiche class Grid { static origin = {x: 0, y: 0}; calculateDistanceFromOrigin(point: {x: number; y: number;}) { let xDist = (point.x - Grid.origin.x); let yDist = (point.y - Grid.origin.y); return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor (public scale: number) { } } let grid1 = new Grid(1.0); // 1x scale let grid2 = new Grid(5.0); // 5x scale console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10})); console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10})); 19 . 8
Classe come interfaccia class Point { x: number; y: number; } interface Point3d extends Point { z: number; } let point3d: Point3d = {x: 1, y: 2, z: 3}; 19 . 9
Modules TypeScript sfrutta un sistema modulare basato sui moduli di ES6! 20 . 1
Modules Sono eseguiti nel loro scope Possono esplicitamente rendere visibili verso l'esterno loro parti (come proprietà, funzioni, etc...) Sono dichiarative Utilizza un module loader come CommonJS o RequireJS Ogni file contenente esportazioni o importazioni è considerato un modulo (come in ES6) 20 . 2
Moduli //file: services.ts // ... export let addtwo = (number) => { number + 2 }; export class MyClass { hi: string; constructor() { this.hi = 'Hi'; } } export const evilNumber = 666; 20 . 3
Moduli // file: app.ts import * as services from "./services"; let inst = new services.MyClass(); let value = services.addtwo(services.evilNumber); 20 . 4
Moduli //Esportazioni possibili export let someValue = 2; export default class MyComponent() {} export { someValue, someOtherValue, andEvenSomeClass } export { someValue as betterName } 20 . 5
Moduli //Importazioni possibili import * as service from './service'; import { someValue, MyClass } from './service'; import { someValue as myLocalName } from './service'; import MyComponent from './my_component'; //solo se export default import './global_module'; // solo side-effects 20 . 6
...e se uso librerie esterne? Posso importarle normalmente. Typescript verificherà la dipendenza nella directory node_modules È necessario utilizzare i typings declaration files (.d.ts) che consentono di descrivere tipi, interfacce e classi per le librerie esistenti. npm supporta i typings con TS 2.0 npm install --save-dev @types/nome_libreria 20 . 7
Moduli //Moduli esterni // > npm install lodash // > npm install "@types/lodash" //Typescript verificherà la dipendenza nella directory node_modules import * as _ from 'lodash'; 20 . 8
Generics I componenti riutilizzabili grazie alla varietà di tipi con i quali possono lavorare! 21 . 1
Generics Consentono la costruzione di componenti riutilizzabili Possano lavorare su una varietà di tipi piuttosto che su uno singolo Generic Type Variables Generic Classes (e Interfaces) Generic Constraints 21 . 2
Generics //Funzione con un tipo definito let pickFirst = (list: number[]): number => { return list[0]; }; //Funzione con tipo any let pickFirst = (list: any[]): any => { return list[0]; }; 21 . 3
Generics //Funzione con generics let pickFirst = <T>(list: T[]): T => { return list[0]; }; // oppure function pickFirst<T>(list: T[]): T { return list[0]; } let res1: string = pickFirst<string>(['1', '2', '3']); let res2: number = pickFirst<number>([1, 2, 3, 4]); let res3: Date = pickFirst<Date>([ new Date(), new Date(), new Date() ]); 21 . 4
Generics class Movie { title: string; } function getAsync<T>(url: string): Promise<T[]> { return fetch(url) .then((response: Response) => response.json()); } getAsync<Movie>("/movies") .then(movies => { movies.forEach(movie => { console.log(movie.title); }); }); 21 . 5
Generics class Queue<T> { private data = []; push = (item: T) => this.data.push(item); pop = (): T => this.data.shift(); } const queue = new Queue<number>(); queue.push(0); queue.push("1"); // ERROR : non pushare una stringa ma solo un tipo numero! 21 . 6
Generics //Funzione con constraint interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // Ora sappiamo che ha la proprietà .length return arg; } 21 . 7
Generics // keyof Constraint function getProperty<T, K extends keyof T> (obj: T, key: K) { return obj[key]; } let x = { a: 1, b: 2, c: 3, d: 4 }; getProperty(x, "a"); // Ok getProperty(x, "m"); // error: l'argomento di tipo 'm' non è assegnabile! 21 . 8
Generics //Interfaccia interface Container<T> { value: T }; let cont: Container<string> = { value: 'test' }; //Classe class GenericCollection<T> { private store: T[]; add(value: T): void { this.store.push(value); } get(index: number): T { return this.store[index]; } } 21 . 9
Decorators Consentono la modifica di classi e membri attraverso semplici annotazioni! 22 . 1
Decorators Sono un tipo speciale di dichiarazione che può essere associata a classi, metodi, proprietà e parametri Utilizzano la forma @expression È possibile rendere parametrici i decorators per mezzo delle Decorator Factory Vengono chiamati quando la classe viene dichiarata, non quando un oggetto viene istanziato Decoratori multipli possono essere definiti sulla stessa classe / proprietà / metodo / parametro Non sono ammessi sui costruttori 22 . 2
Decoratori class MyClass { @log myMethod(arg: string) { return "Message -- " + arg; } } function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) { const originalMethod = descriptor.value; descriptor.value = function(...args: any[]) { console.log("args è: " + JSON.stringify(args)); const result = originalMethod.apply(this, args); console.log("Il valore tornato è: " + result); return result; }; return descriptor; } M Cl () M th d("t ti ") 22 . 3
Decoratori function logged(constructorFn: Function) { console.log(constructorFn); } @logged class Person { constructor() { console.log("Hi!"); } } // Factory function logging(value: boolean) { return function (target) { value ? logged : null; } } 22 . 4
Decoratori class Car { @capitalize modelloVettura(marca: string, modello: string) { return `${marca} - ${modello}`; } } // definizione funzione Decorator capitalize() function capitalize(target: any, propertyKey: string, descriptor: PropertyDes const oldFunction = descriptor.value; console.log('Decorator invocato in fase di definizione della classe') descriptor.value = function(...args: string[]) { const newArgs = args.map( arg => arg.charAt(0).toUpperCase() + arg.slice(1) ) 22 . 5
Decoratori function validate(target: any, propertyKey: string) { let value = target[propertyKey]; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue) => { const pattern = /^[A-Z]{2}s?[0-9]{3}s?[A-Z]{2}$/; if (pattern.test(newValue)) { value = newValue; } else { console.error('Formato targa non valido'); } } }) } class Car { @ lid t 22 . 6
Decoratori interface AutonomousCar { autoPilot: boolean | undefined; startAutoPilot(): void; stopAutoPilot(): void; } interface Constructor<T> { new(...args:any[]):T } function addFeature<T extends Constructor<Car>>(constructor:T) { return class extends constructor implements AutonomousCar { autoPilot: boolean | undefined; startAutoPilot(): void{ this.autoPilot = true; console.log('Autopilot ON'); } 22 . 7
Decoratori // Advanced function printable(constructorFn: Function) { constructorFn.prototype.print = function () { console.log(this); } } @logging(false) @printable class Plant { name = "Green Plant"; } const plant = new Plant(); (<any>plant).print(); 22 . 8
Decoratori // Method Decorator // Property Decorator function editable(value: boolean) { return function (target: any, propName: string, descriptor: PropertyDescr descriptor.writable = value; } } function overwritable(value: boolean) { return function (target: any, propName: string): any { const newDescriptor: PropertyDescriptor = { writable: value }; return newDescriptor; } } 22 . 9
Decoratori // Parameter Decorator function printInfo(target: any, methodName: string, paramIndex: number) { console.log("Target: ", target); console.log("methodName: ", methodName); console.log("paramIndex: ", paramIndex); } class Course { name: string; constructor(name: string) { this.name = name; } printStudentNumbers(mode: string, @printInfo printAll: boolean) { if (printAll) { l l (10000) 22 . 10
Qualche link utile https://www.typescriptlang.org/docs/home.html https://github.com/Microsoft/TypeScript/wiki/What's-new-in- TypeScript https://blogs.msdn.microsoft.com/typescript/ https://www.gitbook.com/book/basarat/typescript/details https://github.com/bitjson/typescript-starter 23

Acadevmy - TypeScript Overview

  • 1.
  • 2.
    Software Factory Web MobileDevOps Labs Formazione 2
  • 3.
  • 4.
  • 5.
  • 6.
    Chi Sono? Developer perscelta e per passione, amante di nerdaggini di ogni tipo ed amante della condivisione del sapere! 5 . 1
  • 7.
    TypeScript oh no, unaltro xyzScript! 6
  • 8.
    TypeScript Javascript che scalao semplicemente... JS con i types! 7
  • 9.
    Breve Storia 2010 -Microsoft inizia lo sviluppo 2012 - Prima Release supportata da Visual Studio 2013 - Supporto ad altri IDE 2014 - TypeScript 1.0 2015 - AtScript viene implementato interamente in TypeScript 2017 - Standard de facto per un Javascript solido! 8
  • 10.
    TypeScript è unsuperset di Javascript 9
  • 11.
    Ricordiamo che... ...per usareES6 (e successivi) è richiesto l'uso di transpiler/compiler: Babel, Traceur, Typescript compiler, ... Tabella di compatibilità 10
  • 12.
  • 13.
    Javascript + Types JS+ ES6/ES7/... + Types Compatibile con JS standard Genera codice JS standard Supporto OOP Implementazione Moduli Compile Time Errors Pensato per Applicazioni Scalabili Solid Development Experience Supporto dei Code Editor Supporto dei Tools (Webpack, Gulp, Grunt, etc...) Colma il GAP di Compatibilità e Produttività 12
  • 14.
    ...e se lodice Anders Hejlsberg... 01:00:36 13
  • 15.
    Strumenti di LavoroFondamentali npm tsc editor/IDE oppure usare per rapide proveTS Playground 14
  • 16.
    Preparare un ambientedi sviluppo essenziale Installare Node (npm) Installare Pacchetti typescript/lite-server come dipendenze di sviluppo Configurazione package.json Configurazione tsconfig.json Creazione Progetto Base (index.html, app.ts) 15
  • 17.
    Creazione di unEnvironment npm init --yes npm install --save-dev typescript lite-server tsc --init // Configura tsconfig ("outDir": "./dist") // Crea index.html // Crea app.ts // Configura package.json: (script: "start": "lite-server & tsc --watch") 16
  • 18.
    Types In Typescript èpossibile definire il tipo di variabili, parametri o valori di ritorno. 17 . 1
  • 19.
    Staticamente tipizzati vsDinamicamente tipizzati “Quando io vedo un uccello che cammina come un’anatra, nuota come un’anatra e starnazza come un’anatra, io chiamo quell’uccello 'anatra'”. Whitcomb Riley 17 . 2
  • 20.
    Types Immediato Feedback inSviluppo Autocomplete e Code-Suggestion contestualizzato Completamente Opzionale Configurazione tsconfig.json 17 . 3
  • 21.
  • 22.
  • 23.
    Type definition let myName= "Francesco"; let otherName: string = "Aurelio"; let num: number = 2; //questo non verrà compilato! num = "test"; let arr: Array<number> = [1, 2, 3, 4]; let arr2: string[] = ["one", "two"]; 17 . 6
  • 24.
    Type definition let addNumbers= (num1: number, num2: number): number => { return num1 + num2; }; let parseString : (input: string) => string; parseString = (input: string) => "un risultato qualunque"; //questo verrà compilato! addNumbers("2", 4); 17 . 7
  • 25.
    Type definition //Tuples let tuple: [string, number]; tuple = ["devil", 666]; tuple[0]; tuple[1]; //enums enum Color {Red, Green, Blue}; let c: Color = Color.Red; if (c === Color.Red) { //farai qualcosa qui... } 17 . 8
  • 26.
    Types (ES6) Scopes delleVariabili Destrutturazione Spread / Rest String Literal 17 . 9
  • 27.
    Scope delle Variabili varfoo; //functional scope let bar; //block scope const baz = "un valore"; //riferimento in sola lettura const value = 2; value = 1; //errato const obj = { name: "Aurelio" }; obj = {}; //errato obj.name = "Francesco"; //ok 17 . 10
  • 28.
    Destrutturazione //Arrays e Tuples let[firsts, second, third] = [1, 2, 3]; console.log(firsts); // 1 console.log(second); // 2 console.log(third); // 3 //objects let {a, b} = { a: "test1", b: "test2" }; let { a: betterName1, b: betterName2 } = { a: "test1", b: "test2" }; //Spread / Rest let arr: number[] = [1, 2]; let concat = [...arr, 3, 4]; let [a, b, ...rest] = concat; 17 . 11
  • 29.
    Template Literals //Template Literals letoldString = 'Una stringa'; let moderString = `Ancora una stringa`; let multilineString = `Questa invece è una stringa multilinea`; //Per i fan degli Iron Maiden let number = 666; let who = 'Beast'; let oldString = number + ' the number of the ' + who; let newString = `${number} the number of the ${who}`; 17 . 12
  • 30.
    Definizione di Funzioni letfun = (param: number): string => { return "string"; }; //parametri opzionali let fun = (arg1: number, arg2?: number) => { //... } //rest let fun2 = (arg1: number, ...restOfArgs: number[]) => { //... }; //valore di default let fun2 = (arg1 = 0) => { // 17 . 13
  • 31.
    Interfacce In Typescript sonoi contratti, che ogni classe (e non solo) che implementa l'interfaccia deve soddisfare. 18 . 1
  • 32.
    Interfacce Descrivono oggetti Definiscono contratto/protocollo Usatesolo in fase di compilazione Molto Flessibili (proprietà dichiarate, opzionali, metodi, etc...) Ereditabili Molto simili alle interfacce Java/C# 18 . 2
  • 33.
    Interfacce //Senza Intefaccia function printLabel(labelledObj:{ label: string }) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj); //Con Intefaccia interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; i tL b l( Obj) 18 . 3
  • 34.
    Interfacce per Oggetti interfaceUser { name: string; surname: string; age?: number; } let me: User = { name: 'Francesco', surname: 'Sciuti', age: 30 // mi piacerebbe tanto }; //questa operazione non è consentita: me.something = 123; 18 . 4
  • 35.
    Interfacce per Oggetti interfacePoint { readonly x: number; readonly y: number; } let p1: Point = { x: 10, y: 20 }; p1.x = 5; // errore! 18 . 5
  • 36.
    Interfacce per Funzioni interfacesearchFunc { (query: string, source: string) : boolean } let mySearch : searchFunc = (q: string, s: string) => { return true; } 18 . 6
  • 37.
    Classi Se ES6 introducele classi in JS, TypeScript le rende migliori! 19 . 1
  • 38.
    Classi Caratteristiche delle classiES6 Sintassi e Leggibilità Migliorata Supporto ad Interfacce (Multiple) Modificatori d'Accesso (public, protected, private) Proprietà Statiche Overload di Metodi e Costruttori Ereditabili Classi Astratte 19 . 2
  • 39.
    Classi //Classe class SayHi { toWho:string; constructor(toWho: string) { this.toWho= toWho; } hi() { return "Hello, " + this.toWho; } } let hi = new SayHi("Francesco"); 19 . 3
  • 40.
    Proprietà class Person { staticsomeStaticAttr = 2; private _id: number; constructor(public name: string, public secondName: string, public age: number) { } } 19 . 4
  • 41.
    Getters and Setters classPerson { //... get fullName():string { return `${this.name} ${this.secondName}`; } set fullName(value:string) { //some parsing probably this.name = valueOfName; this.secondName = valueOfSecondName; } } 19 . 5
  • 42.
    Ereditarietà class Person { protectedname: string; constructor(name: string) { this.name = name; } } class Employee extends Person { private department: string; constructor(name: string, department: string) { super(name); this.department = department; } public sayHi() { return `Ciao, mi chiamo ${this.name}, lavoro a ${this.department}.`; } } 19 . 6
  • 43.
    Implementazione di Interfacce interfaceClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; } constructor(h: number, m: number) { } } 19 . 7
  • 44.
    Proprietà Statiche class Grid{ static origin = {x: 0, y: 0}; calculateDistanceFromOrigin(point: {x: number; y: number;}) { let xDist = (point.x - Grid.origin.x); let yDist = (point.y - Grid.origin.y); return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor (public scale: number) { } } let grid1 = new Grid(1.0); // 1x scale let grid2 = new Grid(5.0); // 5x scale console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10})); console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10})); 19 . 8
  • 45.
    Classe come interfaccia classPoint { x: number; y: number; } interface Point3d extends Point { z: number; } let point3d: Point3d = {x: 1, y: 2, z: 3}; 19 . 9
  • 46.
    Modules TypeScript sfrutta unsistema modulare basato sui moduli di ES6! 20 . 1
  • 47.
    Modules Sono eseguiti nelloro scope Possono esplicitamente rendere visibili verso l'esterno loro parti (come proprietà, funzioni, etc...) Sono dichiarative Utilizza un module loader come CommonJS o RequireJS Ogni file contenente esportazioni o importazioni è considerato un modulo (come in ES6) 20 . 2
  • 48.
    Moduli //file: services.ts // ... exportlet addtwo = (number) => { number + 2 }; export class MyClass { hi: string; constructor() { this.hi = 'Hi'; } } export const evilNumber = 666; 20 . 3
  • 49.
    Moduli // file: app.ts import* as services from "./services"; let inst = new services.MyClass(); let value = services.addtwo(services.evilNumber); 20 . 4
  • 50.
    Moduli //Esportazioni possibili export letsomeValue = 2; export default class MyComponent() {} export { someValue, someOtherValue, andEvenSomeClass } export { someValue as betterName } 20 . 5
  • 51.
    Moduli //Importazioni possibili import *as service from './service'; import { someValue, MyClass } from './service'; import { someValue as myLocalName } from './service'; import MyComponent from './my_component'; //solo se export default import './global_module'; // solo side-effects 20 . 6
  • 52.
    ...e se usolibrerie esterne? Posso importarle normalmente. Typescript verificherà la dipendenza nella directory node_modules È necessario utilizzare i typings declaration files (.d.ts) che consentono di descrivere tipi, interfacce e classi per le librerie esistenti. npm supporta i typings con TS 2.0 npm install --save-dev @types/nome_libreria 20 . 7
  • 53.
    Moduli //Moduli esterni // >npm install lodash // > npm install "@types/lodash" //Typescript verificherà la dipendenza nella directory node_modules import * as _ from 'lodash'; 20 . 8
  • 54.
    Generics I componenti riutilizzabiligrazie alla varietà di tipi con i quali possono lavorare! 21 . 1
  • 55.
    Generics Consentono la costruzionedi componenti riutilizzabili Possano lavorare su una varietà di tipi piuttosto che su uno singolo Generic Type Variables Generic Classes (e Interfaces) Generic Constraints 21 . 2
  • 56.
    Generics //Funzione con untipo definito let pickFirst = (list: number[]): number => { return list[0]; }; //Funzione con tipo any let pickFirst = (list: any[]): any => { return list[0]; }; 21 . 3
  • 57.
    Generics //Funzione con generics letpickFirst = <T>(list: T[]): T => { return list[0]; }; // oppure function pickFirst<T>(list: T[]): T { return list[0]; } let res1: string = pickFirst<string>(['1', '2', '3']); let res2: number = pickFirst<number>([1, 2, 3, 4]); let res3: Date = pickFirst<Date>([ new Date(), new Date(), new Date() ]); 21 . 4
  • 58.
    Generics class Movie {title: string; } function getAsync<T>(url: string): Promise<T[]> { return fetch(url) .then((response: Response) => response.json()); } getAsync<Movie>("/movies") .then(movies => { movies.forEach(movie => { console.log(movie.title); }); }); 21 . 5
  • 59.
    Generics class Queue<T> { privatedata = []; push = (item: T) => this.data.push(item); pop = (): T => this.data.shift(); } const queue = new Queue<number>(); queue.push(0); queue.push("1"); // ERROR : non pushare una stringa ma solo un tipo numero! 21 . 6
  • 60.
    Generics //Funzione con constraint interfaceLengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // Ora sappiamo che ha la proprietà .length return arg; } 21 . 7
  • 61.
    Generics // keyof Constraint functiongetProperty<T, K extends keyof T> (obj: T, key: K) { return obj[key]; } let x = { a: 1, b: 2, c: 3, d: 4 }; getProperty(x, "a"); // Ok getProperty(x, "m"); // error: l'argomento di tipo 'm' non è assegnabile! 21 . 8
  • 62.
    Generics //Interfaccia interface Container<T> { value:T }; let cont: Container<string> = { value: 'test' }; //Classe class GenericCollection<T> { private store: T[]; add(value: T): void { this.store.push(value); } get(index: number): T { return this.store[index]; } } 21 . 9
  • 63.
    Decorators Consentono la modificadi classi e membri attraverso semplici annotazioni! 22 . 1
  • 64.
    Decorators Sono un tipospeciale di dichiarazione che può essere associata a classi, metodi, proprietà e parametri Utilizzano la forma @expression È possibile rendere parametrici i decorators per mezzo delle Decorator Factory Vengono chiamati quando la classe viene dichiarata, non quando un oggetto viene istanziato Decoratori multipli possono essere definiti sulla stessa classe / proprietà / metodo / parametro Non sono ammessi sui costruttori 22 . 2
  • 65.
    Decoratori class MyClass { @log myMethod(arg:string) { return "Message -- " + arg; } } function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) { const originalMethod = descriptor.value; descriptor.value = function(...args: any[]) { console.log("args è: " + JSON.stringify(args)); const result = originalMethod.apply(this, args); console.log("Il valore tornato è: " + result); return result; }; return descriptor; } M Cl () M th d("t ti ") 22 . 3
  • 66.
    Decoratori function logged(constructorFn: Function){ console.log(constructorFn); } @logged class Person { constructor() { console.log("Hi!"); } } // Factory function logging(value: boolean) { return function (target) { value ? logged : null; } } 22 . 4
  • 67.
    Decoratori class Car { @capitalize modelloVettura(marca:string, modello: string) { return `${marca} - ${modello}`; } } // definizione funzione Decorator capitalize() function capitalize(target: any, propertyKey: string, descriptor: PropertyDes const oldFunction = descriptor.value; console.log('Decorator invocato in fase di definizione della classe') descriptor.value = function(...args: string[]) { const newArgs = args.map( arg => arg.charAt(0).toUpperCase() + arg.slice(1) ) 22 . 5
  • 68.
    Decoratori function validate(target: any,propertyKey: string) { let value = target[propertyKey]; Object.defineProperty(target, propertyKey, { get: () => value, set: (newValue) => { const pattern = /^[A-Z]{2}s?[0-9]{3}s?[A-Z]{2}$/; if (pattern.test(newValue)) { value = newValue; } else { console.error('Formato targa non valido'); } } }) } class Car { @ lid t 22 . 6
  • 69.
    Decoratori interface AutonomousCar { autoPilot:boolean | undefined; startAutoPilot(): void; stopAutoPilot(): void; } interface Constructor<T> { new(...args:any[]):T } function addFeature<T extends Constructor<Car>>(constructor:T) { return class extends constructor implements AutonomousCar { autoPilot: boolean | undefined; startAutoPilot(): void{ this.autoPilot = true; console.log('Autopilot ON'); } 22 . 7
  • 70.
    Decoratori // Advanced function printable(constructorFn:Function) { constructorFn.prototype.print = function () { console.log(this); } } @logging(false) @printable class Plant { name = "Green Plant"; } const plant = new Plant(); (<any>plant).print(); 22 . 8
  • 71.
    Decoratori // Method Decorator //Property Decorator function editable(value: boolean) { return function (target: any, propName: string, descriptor: PropertyDescr descriptor.writable = value; } } function overwritable(value: boolean) { return function (target: any, propName: string): any { const newDescriptor: PropertyDescriptor = { writable: value }; return newDescriptor; } } 22 . 9
  • 72.
    Decoratori // Parameter Decorator functionprintInfo(target: any, methodName: string, paramIndex: number) { console.log("Target: ", target); console.log("methodName: ", methodName); console.log("paramIndex: ", paramIndex); } class Course { name: string; constructor(name: string) { this.name = name; } printStudentNumbers(mode: string, @printInfo printAll: boolean) { if (printAll) { l l (10000) 22 . 10
  • 73.