# Typescript è meglio

Typescript logo

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: Editor iniziale

# 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. Prima versione 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!

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... errore: length non esiste per il tipo unknown

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... senza nome e poi augusto

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)

Comment Form is loading comments...