TypeScript ha cambiato il modo di scrivere JavaScript ed in questo talk andiamo a scoprirne le principali caratteristiche per scrivere "JavaScript che non si rompe!"
N.B. Le slides sono aggiornate sino a TS 3.
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
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 lo dice Anders Hejlsberg...
01:00:36
13
15. Strumenti di Lavoro Fondamentali
npm
tsc
editor/IDE
oppure usare per rapide proveTS Playground
14
16. 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
18. Types
In Typescript è possibile definire il tipo di
variabili, parametri o valori di ritorno.
17 . 1
19. 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
20. Types
Immediato Feedback in Sviluppo
Autocomplete e Code-Suggestion contestualizzato
Completamente Opzionale
Configurazione tsconfig.json
17 . 3
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
29. 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
30. 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
31. Interfacce
In Typescript sono i contratti, che ogni classe (e non
solo) che implementa l'interfaccia deve soddisfare.
18 . 1
47. 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
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 let someValue = 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 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
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
55. 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
56. 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
57. 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
59. 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
60. 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
61. 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
64. 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
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