# Typescript è meglio
Typescript è un linguaggio simile a Javascript ma con molti vantaggi rispetto ad esso. La caratteristica principale è il supporto dei tipi. Questo si traduce immediatamente nella possibilità di intercettare molti errori direttamente nell’ambiente di sviluppo, un refactoring più semplice ed affidabile e nella possibilità di usare l’autocompletamento quando stiamo scrivendo il codice.
Se siete esperti di Javascript ma non ve la sentite di imparare un nuovo linguaggio, beh niente paura: Javascript è Typescript! Quando Microsoft ha creato questo linguaggio ha praticamente preso Javascript e ha reso i tipi opzionali, quindi un qualsiasi codice Javascript vale come Typescript.
Ovviamente il contrario non è vero. Un programma Typescript ha bisogno di essere compilato per generare Javascript, ma questo, come vedremo fra poco, è una procedura alquanto semplice.
# Creiamo un’applicazione di esempio
Nel tutorial che segue andremo a creare una piccola applicazione che da linea di comando chiede il nostro nome (con insistenza!) e ci saluta.
# Preparazione ambiente di sviluppo
Prima di tutto installa Typescript
npm install -g typescript
Poi crea una directory in cui potrai svolgere il lavoretto. All’interno inizializza un progetto con yarn
o npm
, userò quest’ultimo.
npm init
npm install --save @types/node
Con l’ultimo comando hai installato @types/node
che ti darà accesso ai tipi per interfacciarsi con le API di Node.
Per questo tutorial userò VS Code, ma qualunque IDE che supporta Typescript dovrebbe andare.
Ecco quello che dovresti vedere:
# Programma in stile Javascript
Nella cartella del progetto crea un nuovo file index.ts
dove l’estensione .ts
sta ad indicare che si tratta di un programma Typescript.
Il seguente è la prima versione del programma.
import { createInterface } from 'readline'
const getStrLn = () =>
new Promise(resolve => {
const rl = createInterface({
input: process.stdin,
output: process.stdout
})
rl.question('> ', answer => {
rl.close()
resolve(answer)
})
})
const putStrLn = msg => console.log(msg)
const askName = () => putStrLn('Ciao, come ti chiami?')
askName(); getStrLn().then(name =>
putStrLn(`Heylà ${name}!`)
)
Prima di descrivere brevemente cosa succede, lancia il programma con il seguente comando
ts-node index.ts
Se tutto va bene dovresti riuscire ad interagire con un semplice programma.
Il codice che hai appena scritto è Javascript al 99% se non fosse che Node non capisce i moduli (il comando import
alla prima riga) potresti tranquillamente farlo girare su Node.
Retrocompatibilità
Prova a sostituire l’import
con un require
e lancia l’applicazione con node index.ts
per convincerti che è Javascript valido.
# Mini spiegazione
La prima funzione getStrLn
restituisce una Promise
che, grazie alle API di Node prende una linea da linea di comando, questa verra restituita “risolvendo” la promessa. putStrLn
prende una stringa e la scrive a console, niente di nuovo sotto il sole. Infine mettiamo tutto insieme alla fine. Con askName
chiediamo il nome e usiamo il risultato della promessa per stampare un saluto a schermo.
Se hai dei dubbi scrivi pure un commento sotto, cercherò di rispondere il prima possibile.
# Gestione degli errori?
Cosa succede al nostro programma se diamo invio senza scrivere alcunché? Saluta una stringa vuota; totalmente inaccettabile!
Vogliamo che il programma ci ripeta la domanda insistentemente finché non rispondiamo.
Ok, come fare?
Raccogliamo tutti i comandi sparsi alla fine in una più ordinata e professionale funzione:
const main = () => {askName(); getStrLn().then(name =>
putStrLn(`Heylà ${name}!`)
)}
main()
Da qui possiamo controllare se il nome è una stringa vuota e chiedere di nuovo il nome:
const main = () => {askName(); getStrLn().then(name => {
if (name.length != 0)
putStrLn(`Heylà ${name}!`)
else
main()
})}
A questo punto, se usi Code o un ambiente di sviluppo avanzato, dovresti già vedere sottolineato l’errore di compilazione. Per gli altri basta provare a lanciare il programma e...
Sembra che il compilatore si lamenti del fatto che name
, in quanto di tipo sconosciuto, non abbia una proprietà chiamata length
. Questo è il sistema di tipi che entra in azione e ci aiuta a prevenire il classico errore runtime. Per dimostrare al compilatore che abbiamo ragione noi possiamo dichiarare name
come tipo stringa.
const main = () => {askName(); getStrLn().then((name: String) => {
if (name.length != 0)
putStrLn(`Heylà ${name}!`)
else
main()
})}
Perfetto, lanciamo il programma e...
Tutto sembra funzionare.
Programma non stack-safe
Da notare che il programma che abbiamo scritto non è certo pronto per un rilascio in produzione. In particolare se rifiutiamo di dare il nome abbastanza volte Node esaurirà la memoria perché dovrà allocare lo spazio per chiamare la funzione main
molte volte. Bisognerebbe trasformare la chiamata ricorsiva in un ciclo.
# Conclusione
È possibile imparare il Typescript passo passo, partendo da codice Javascript e aggiungendo i tipi quando serve. Con una curva di apprendimento più lieve, possiamo lasciare per dopo caratteristiche avanzate del linguaggio e portare comunque avanti il lavoro. Typescript ci permette di avere un Javascript più corretto con l’aiuto del compilatore, il tempo impiegato ad impararlo sicuramente ripaga in fretta e grazie ai tipi statici è più difficile malinterpretare il codice stritto da un nostro collega e più facile leggerlo.
Typescript è meglio... di Javascript. Onestamente non ci vuole molto, ma typescript si deve portare dietro tutti i difetti di JS. In prossimo articolo vorrei parlare di Purescript o Elm, due linguaggi che compilano a Javavascript ma decisamente più potenti.
Andrea Passaglia (opens new window)