TypeScript, il labirinto della tipizzazione in JavaScript

Con un focus su configurazioni sofisticate e gestione efficace dei tipi, TypeScript domina le applicazioni JavaScript. Esaminiamo insieme i suoi aspetti più potenti!

TypeScript, il labirinto della tipizzazione in JavaScript

Introduzione a TypeScript: eleviamo la qualità del nostro codice

TypeScript, super-set di JavaScript, si è posizionato come una scelta prioritaria per gli sviluppatori intenti a migliorare la scalabilità e la manutenibilità dei propri progetti software. Sebbene JavaScript sia ideale per lo sviluppo di soluzioni rapide e per siti web dinamici, TypeScript introduce una tipizzazione statica rigorosa che aiuta a prevenire numerosi errori di programmazione comuni, contribuendo così a solidificare la base del codice e a semplificarne la gestione.

Optare per TypeScript piuttosto che per JavaScript può dipendere da vari fattori, tra cui la complessità del progetto e la necessità di mantenere il codice facilmente gestibile nel tempo.

TypeScript infatti, risulta essere particolarmente vantaggioso per progetti di grandi dimensioni o per quelli che coinvolgono team numerosi, dove la precisione nella documentazione dei tipi di dato e la trasparenza del codice, assumono un'importanza cruciale.

L'Importanza della Tipizzazione

In un'epoca in cui i software diventano sempre più complessi e integrati, l'importanza di aspettarsi un tipo di dato specifico non può essere sottovalutata. La tipizzazione statica di TypeScript permette agli sviluppatori di definire esplicitamente i tipi di dati che le loro variabili dovrebbero contenere, riducendo così gli errori in fase di esecuzione e migliorando la qualità del software. Questa precisione non solo facilita la lettura e la manutenzione del codice, ma migliora anche la collaborazione tra sviluppatori, permettendo al team di capire rapidamente la struttura e il funzionamento del software.

Dopo questa introduzione base, andiamo a scoprire le sue funzionalità e come utilizzarlo nel nostro progetto!

Configurazione base

Prima di procedere, è importante avere un ambiente di sviluppo adeguato che includa il supporto per Node.js.

Terminal
mkdir mio-progetto-typescript // creiamo la cartella del nostro progetto cd mio-progetto-typescript
Terminal
// installiamo typescript globalmente npm install -g typescript

Dopo aver installato TypeScript, puoi inizializzare il tuo progetto per creare un file tsconfig.json che definisce le opzioni del compilatore.

Questo è un passaggio essenziale per configurare adeguatamente il tuo ambiente di sviluppo. Puoi procedere attraverso il comando messo a disposizione dopo l'installazione globale di TypeScript

Terminal
tsc --init

Questo comando genera automaticamente un file tsconfig.json con configurazioni predefinite.

Questo file è fondamentale in un progetto TypeScript perché definisce come il compilatore deve comportarsi durante la trasformazione del codice TypeScript in JavaScript

La sua personalizzazione ti permette di adattare il processo di compilazione alle specifiche necessità del tuo progetto, influenzando l'output, la performance, e la compatibilità del codice

JavaScript
// TypeScript { "compilerOptions": { "target": "es2016", // Specifica la versione ECMAScript di output per il codice JavaScript compilato "module": "commonjs", // Definisce il sistema di moduli usato nel progetto (ad es. CommonJS, ES6, etc.) "strict": true, // Abilita una versione più rigorosa della tipizzazione, per una maggiore sicurezza del codice "outDir": "dist", // Percorso in cui il compilatore depositerà i file JavaScript compilati dopo la build "esModuleInterop": true, // Consente l'importazione di moduli ES6 nel progetto TypeScript "skipLibCheck": true, // Salta la verifica dei file di definizione delle librerie per velocizzare la compilazione "forceConsistentCasingInFileNames": true // Assicura che l'uso della capitalizzazione nei nomi dei file sia consistente } }

type vs interface

In TypeScript, type e interface sono due costrutti che permettono di definire strutture di dati e tipi di contratto. Sebbene siano simili, presentano alcune differenze chiave:

interface: particolarmente utili per definire la struttura degli oggetti che devono essere implementati. Sono ideali per la programmazione orientata agli oggetti in TypeScript perché possono essere estese o implementate da altre interfacce. Ciò permette di costruire strutture di tipo gerarchiche e riutilizzabili. Gli oggetti che implementano un'interfaccia devono aderire alla struttura definita da quella interfaccia, il che facilita la consistenza e la manutenibilità del codice

type: definiti alias offrono una flessibilità maggiore rispetto alle interfacce. Possono rappresentare non solo forme di oggetto, ma anche unioni, intersezioni e tipi primitivi. Ciò li rende estremamente versatili per casi d'uso che richiedono combinazioni di tipi o restrizioni specifiche che non si adattano facilmente al modello delle interfacce

Vediamo insieme un esempio che utilizza sia interface che type :

JavaScript
// type-interface.ts // definizione di un type per gli attributi base di un artista type Artist = { name: string; code: string; }; // definizione di un'interfaccia per una funzione che gestisce informazioni sugli artisti interface ArtistInfoFunction { (artist: Artist): string; } // implementazione di una funzione che corrisponde all'interfaccia ArtistInfoFunction const showArtistInfo: ArtistInfoFunction = (artist) => { return `Artist: ${artist.name}, code: ${artist.code}`; }; // utilizzo della funzione con un artista specifico const artist = { name: "artCode", code: "TypeScript" }; console.log(showArtistInfo(artist));

type Artist: Questo type definisce una struttura per i dati dell'artista, indicando che ogni artista avrà un name e un dato "code" di tipo string. I type sono flessibili e possono essere utilizzati per creare tipi di dati compositi, inclusi quelli per funzioni, array, tuple e altro.

Interface ArtistInfoFunction: Questa interfaccia specifica che qualsiasi funzione che corrisponda a questa interfaccia deve accettare un parametro di tipo Artist e restituire una stringa. L'uso di interfacce per definire le firme delle funzioni aiuta a garantire che le funzioni in diversi parti del codice seguano lo stesso schema, facilitando la gestione e il mantenimento del codice

Concludiamo, dicendo che utilizzare interface per le firme delle funzioni è particolarmente utile in scenari più grandi e complessi dove molteplici funzioni potrebbero interagire o essere scambiate tra diversi componenti o moduli

Enum

Gli Enum sono una funzionalità che permette di definire un set di costanti nominate, migliorando la leggibilità del codice

JavaScript
// TypeScript enum Direction { Up, Down, Left, Right } let direzione: Direction = Direction.Up;

Operatori e asserzioni

In TypeScript, puoi usare l'asserzione di tipo quando sei certo del tipo di una variabile in un determinato contesto, ma non può dedurlo in autonomia. Questo è spesso il caso quando si lavora con tipi any o durante l'interfacciamento con librerie JavaScript non tipizzate.

JavaScript
// Typescript // esempio con string e number let someValue: any = "artCode 2024"; let stringLength: number = (someValue as string).length; console.log(`Lunghezza stringa: ${stringLength}`);

In questo esempio, someValue è dichiarato come any, ma tramite l'asserzione (someValue as string), informiamo TypeScript che someValue è una stringa, permettendo così l'accesso sicuro alla proprietà .length!

Dopo aver scritto il tuo codice in TypeScript, è essenziale sapere come trasformarlo in JavaScript eseguibile e come semplificare il processo di sviluppo attraverso l'uso del watcher.

Compilazione: una volta che hai scritto il tuo script in un file .ts, puoi compilare il codice in JavaScript usando il compilatore TypeScript. Apri il terminale nella directory del tuo file e digita:

Terminal
tsc nome-file.ts

Questo comando converte il tuo file TypeScript nome-file.ts in un file JavaScript nome-file.js

Esecuzione: per eseguire il file JavaScript risultante, utilizza Node.js

JavaScript
node nome-file.js

Per rendere il processo di sviluppo più fluido, TypeScript offre una funzionalità di "watching" che rileva automaticamente le modifiche ai file TypeScript e li ricompila in tempo reale. Questo è particolarmente utile durante lo sviluppo attivo, poiché elimina la necessità di ricompilare manualmente il codice dopo ogni modifica

Terminal
tsc --watch nome-file.ts

Questo comando avvierà un processo che monitora il file specificato (e tutti i file correlati, se configurato nel tsconfig.json) e ricompila automaticamente il codice ogni volta che viene salvata una modifica.

Usare il watcher può notevolmente velocizzare il tuo flusso di lavoro di sviluppo, permettendoti di vedere gli effetti delle tue modifiche quasi istantaneamente senza dover eseguire manualmente il comando di compilazione ogni volta

Implementando queste pratiche nel tuo flusso di lavoro di sviluppo TypeScript, potrai sfruttare appieno le capacità del linguaggio per scrivere codice più sicuro e mantenibile, mentre mantieni un ambiente di sviluppo efficiente e reattivo!

E tu? Cosa ne pensi? Utilizzi o utilizzerai TypeScript nei tuoi progetti futuri?