#howtodev - Introduzione a typescript

Scritto da il
Redatto da
javascript
typescript
node

Javascript #chaiproblemigrossi, quindi Microsoft ha ben pensato di strutturarci sopra un linguaggio che ne risolvesse i problemi principali, come la tipizzazione debole.

TypeScript becomes JavaScript via the delete key

~ typescriptlang.org

Obiettivi

In questo articolo vedremo :

  • come compilare typescript ed eseguirlo
  • sintassi dei commenti
  • variabili primitive
  • array e tuple
  • stampare a schermo
  • enumerazioni
  • custom object ( json )

Prerequisiti

Per eseguire javascript e installare typescript avete bisogno di node e npm. Per comprendere a pieno l’articolo serviranno:

  • Conoscenze base di javascript
  • Conoscenze base di programmazione procedurale
  • Conoscenze base di logica di programmazione ( i.e. logica booleana)

Testare typescript in locale

Per testare typescript si deve installare il compilatore tramite npm:

npm install -g typescript

Quindi si può compilare il file con il suo cli, tsc:

tsc nomefile.ts

Nota:

Normalmente i file con estensione ts con TypeScript

Una volta compilato, troveremo un file javascript da poter testare come meglio sappiamo fare, ad esempio tramite node:

node nomefile.js  

Target di compilazione

In alcuni casi potrebbe essere necessario cambiare target di compilazione, cioè specificare che quel file verrà eseguito con una versione specifica di javascript più che un altra. Ad esempio supponiamo di voler eseguire Typescript con versioni di javascript da es6 in poi:

tsc -t es6 file.ts

Va poi ovviamente eseguito in modo appropriato anche con node:

node --harmony file.js

Debug

Il debug su typescript va impostato seguendo alcuni passaggi. Innanzitutto va creato il così detto “source map” che aiuta il debugger di node a capire quale istruzione js corrisponde a quale istruzione typescript. In fase di compilazione di ts scrivere :

tsc --sourceMap true nomefile.ts

Quindi dobbiamo dire a node di andare in modalità debug, ma nel farlo specificheremo di non eseguire il file se non vi è attaccato alcun debugger:

node --inspect-brk nomefile.js

Quindi ci uscirà in output indirizzo e porta di debug, normalmente:

127.0.0.1:9229

A quel punto possiamo chiedere al nostro IDE di connettersi a quel websocket remoto per il debug

Commenti

Esistono due tipi di commenti in ts, inline:

// commento inline

oppure a blocco:

/*
commento 
su
più
righe
*/

Variabili

Le variabili si possono dichiarare nella maniera classica di javascript:

var lettera="a";
var buleano=true;
let numero=0;
const stringa="aaaaaaaa";

Tuttavia, volendo sfruttare quelli che sono i meccanismi di TypeScript, potremmo specificare la tipologia di ogni variabile dopo il suo nome, separato dal carattere :

var lettera:string="a";
var buleano:boolean=true;
let numero:number=0;
const stringa:string="aaaaaaaa";

String concat e String interpolation

Si possono “sommare” due stringhe così facendo:

let stringa1: string="ciao";
let stringa2: string=" come stai?";
let stringaSomma: string=stringa1+stringa2; // diventa = "ciao come stai?"

Questa operazione è detta concatenazione.

La concatenazione è possibile anche con altre variabili non di tipo stringa:

let stringa1: string="ciao";
let variabile:number=3
let stringaSomma: string=stringa1+variabile;// diventa = "ciao3"

Il risultato verrà poi convertito in tipo stringa ovviamente.

Le stringhe permettono anche l’utilizzo del concetto di interpolazione, un’operazione che consente di inserire delle variabili all’interno di una stringa, senza usare la somma, ma richiamando le variabili direttamente al suo interno. Per farlo bisogna creare le stringhe con il backtick (carattere `) ed inserire le singole variabili all’interno della combinazione ${}

let codice:number=9
let stringa:string=`Identità numero ${numero}!` // diventa="Identità numero 9!"

Console log

Per stampare una variabile possiamo usare la console log :

console.log(nomevariabile)

Genericamente il console log fa il casting automatico delle variabili in stringhe, perciò è comune scrivere al suo interno direttamente le stringhe sommate o interpolate:

console.log("La variabile x ha valore "+x)
console.log(`La variabile y ha valore ${y}`)

Tuttavia, questo metodo, nella sua implementazione, prende un numero infinito di stringhe che poi concatena automaticamente separandole tramite degli spazi. Non è quindi affatto strano trovarsi di fronte ad un tipo di sintassi simile:

console.log("La variabile x ha valore",x,"e la variabile y ha valore",y)

Usare console.log senza andare a capo

Non esiste un modo per non andare a capo con console.log, ma potete ovviare: create una stringa con ciò che volete stampare costruendola passo passo senza new lines

Array

Si può specificare il tipo array con la sintassi:

var vettore_numeri:number[] = [18,18,30];

Alternativamente, lo si può fare anche con il tipo Array<number> .

Sugli array si possono eseguire le normali operazioni di javascript, segue esempio sulla media :

let vettore_numeri:Array<number> = [18,30,18,21]

console.log("vettore_numeri:"+vettore_numeri);

console.log("lunghezza vettore:"+vettore_numeri.length);

let media:number=0;
for ( let i in vettore_numeri) { 
        media=media+vettore_numeri[i]/vettore_numeri.length; 
}

console.log("media=",media);

Si può inserire un valore in un vettore attraverso il metodo push:

let nomi:string[] = ["davide","giulia","giovanni"]
nomi.push("emanuela")

Oppure usando l’indice della lunghezza del vettore:

let nomi:string[] = ["davide","giulia","giovanni"]
nomi[nomi.length]="emanuela";

Ancora, si può usare il metodo concat, che permette anche di aggiungere interi vettori.

Scorrere un array per indice

Per scorrere un array abbiamo diversi meccanismi.

Possiamo scorrere i vari indici attraverso la parolina in

for (let i in vettore) {
 console.log(`${i} \u00e8 l'indice di ${vettore[i]} nel vettore`);
}

NB:

l’indice viene però prelevato come se fosse una stringa, quindi non potete utilizzarlo poi per calcoli matematici a meno di conversioni.

Scorrere un array per valore

Alternativamente possiamo scorrere direttamente i valori attraverso la parolina of

for (let val of vettore) {
 console.log(`${val} \u00e8 un elemento del vettore`);
}

Tuple

Le tuple sono vettori nei quali deve essere definito a priori il tipo di ogni cella. Questo tipo, che non è nativamente presente in javascript, è stato introdotto in typescript.

Supponiamo di voler definire un vettore che rappresenta nome,cognome ed età :

var persona: [string,string, number]= ["Davide","Galati",30]

Se proviamo ad assegnare una combinazione diversa di tipi, ad esempio stringa, numero e stringa, succederà questo :

persona: [string,string, number]= ["Davide",30,"Galati"]

L’output sarà:

esempi.ts:40:20 - error TS2322: Type 'number' is not assignable to type 'string'.

40 persona= ["Davide",30,"Galati"];
                      ~~

esempi.ts:40:23 - error TS2322: Type 'string' is not assignable to type 'number'.

40 persona= ["Davide",30,"Galati"];
                         ~~~~~~~~

Le tuple hanno una dimensione prefissata, perciò se proviamo a creare una nuova cella (persona[4]=123) avremo in output un errore:

esempi.ts:46:9 - error TS2493: Tuple type '[string, string, number]' of length '3' has no element at index '4'.

46 persona[4]=123
           ~

Possiamo comunque utilizzare il metodo concat per creare una nuova variabile:

console.log(persona.concat(123))

Enumerazioni

Typescript possiede il tipo “enumerazione” che crea delle costanti identificate dal loro nome, molto comode da usare:

enum BIBITE {
    ACQUA,
    COCACOLA,
    FANTA
}

Per l’utilizzo:

var bibita:BIBITE=BIBITE.ACQUA;

Quindi si può stampare il suo valore numerico:

console.log("Il suo numero ordinale=",bibita)

output:

0

L’enumerazione viene inizializzata come una sorta di vettore, quindi per avere il suo valore stringa bisogna accedervi utilizzando il numero ordinale all’intera enumerazione. Così:

console.log("valore stringa="BIBITE[bibita])

output:

ACQUA

Per ottenere questa relazione biunivoca, sotto la scocca l’enumerazione viene vista come un json valido da un lato e da un altro. Per essere chiari, stampando un’intera enumerazione si ottiene questo :

tutte le bibite= {
  '0': 'ACQUA',
  '1': 'COCACOLA',
  '2': 'FANTA',
  ACQUA: 0,
  COCACOLA: 1,
  FANTA: 2
}

Così facendo, se si chiede l’elemento ‘0’ viene restituita la stringa “ACQUA”, ma se si chiede l’elemento “ACQUA” viene restituito anche lo ‘0

Quest’operazione è anche detta Reverse mapping .

Enumerazioni : AVANZATE

Si può assegnare, alle enumerazioni, un valore ben preciso, supponiamo questo esempio con i colori:

enum COLORI {
    ROSSO="#FF0000",
    VERDE="#00FF00",
    BLUE="#0000FF"
}

In questo modo, quando andremo ad utilizzare l’enumerazione, il suo valore numerico sarà sostituito dal valore che gli abbiamo dato.

Stampando:

console.log(COLORI.ROSSO)

La risposta sarà:

#FF0000

Ma cosa succede al Reverse mapping? Sostanzialmente si perde, infatti se proviamo a stampare l’enumerazione scopriremo che le relazioni non sono più biunivoche:

console.log("Tutti i colori=",COLORI);

output:

Tutti i colori= { ROSSO: '#FF0000', VERDE: '#00FF00', BLUE: '#0000FF' }

E se proviamo ad applicare lo stesso la tecnica di sopra, otterremo un valore totalmente errato :

console.log("valore colore rosso errato =",COLORI[rosso]);   

output:

valore colore rosso errato = undefined

Come facciamo quindi a recuperare il valore delle chiavi? Sfruttiamo una funzione nativa di Object, ovvero keys:

var nomicolori= Object.keys(COLORI) ;
console.log("valore stringa colore rosso =", nomicolori[0]);

output:

valore stringa colore rosso = ROSSO

Resta comunque possibile ciclare, con un for, in automatico tutte le chiavi di un’enumerazione, così:

for (let i in COLORI){ 
        console.log(i);
}

output:

ROSSO
VERDE
BLUE

Tipo any

Una dichiarazione che non ha vincoli di alcun tipo ( come in javascript, per intenderci ) sottointende, in typescript, il tipo any.

Questo può essere usato come tipo in inizializzazioni di qualunque genere, variabili o vettori, e viene considerato implicito se non è stato definito nessun tipo nell’inizializzazione di una variabile :

let variabile="sono una stringa" // questa variabile è di tipo any

let variabilequalunque:any="sono una stringa qualunque" // anche questa variabile  

Questo tipo è molto comodo nei metodi, nel tipo di ritorno oppure nelle tuple, dove è necessario dichiarare a priori dei tipi. Altresì si potrebbe utilizzare per creare dei vettori di elementi di tipi misti.

Tipo void

Il void è invece utilizzato nelle funzioni per annunciare l’assenza di un valore di ritorno

function nomeFunzione():void{
    //cose
}

Si può creare una variabile di tipo void ma deve essere poi necessariamente associata al valore null o undefined.

Un esempio di utilizzo:

let nullo:void=null
let indefinito:void = undefined

console.log("nullo=",nullo)
console.log("indefinito=",indefinito)

output:

nullo= null
indefinito= undefined

Ecco invece cosa succede ad assegnare un valore non valido:

let asd:void="ciao"

output:

esempi.ts:107:5 - error TS2322: Type 'string' is not assignable to type 'void'.

107 let asd:void="ciao"

Oggetti o json

Possiamo creare al volo un tipo custom, un json, formato da più tipi primitivi al suo interno. Ecco come:

var oggetto:{valore1:number,valore2:string};

Dopo va inizializzato come segue:

oggetto={valore1:1,valore2:"nome"};

Possiamo quindi richiamare ogni singolo valore all’interno dell’oggetto usando la sintassi nomeoggetto.nomevariabile :

console.log("valore 1 dell'oggetto=",oggetto.valore1);

Tipi definiti come variabili

Possiamo crearci un nuovo tipo dandogli un nome con la direttiva type.

Creiamoci ad esempio un tipo: libro, che è un oggetto con nome e descrizione:

type libro = {nome:string,autore:string}

Quindi assegnamo una variabile di tipo libro, ad esempio la variabile hp:

var hp:libro= {nome:"harry potter: la pietra filosofale",autore:"J.K.Rowling"}

Questo potrebbe facilitare la lettura nonché il riutilizzo di oggetti specifici.

Possiamo anche definire un tipo come l’unione di più tipi, ad esempio il tipo alfanum, che può essere un number o una stringa:

type alfanum = string | number;

E quindi inizializzarle una variabile come alfanum tanto con una stringa quanto con un numero:

let v1:alfanum = "ciao";
let v2:alfanum = 1;
history_edu Revisioni