Il tutorial completo per imparare TypeScript da zero: tipi, generics, interfacce, classi, utility types, decorators, async e molto altro.
Introduzione a TypeScript
TypeScript è un linguaggio di programmazione open-source sviluppato da Microsoft che estende JavaScript aggiungendo la tipizzazione statica opzionale. Il codice TypeScript viene compilato (transpilato) in JavaScript puro, quindi gira ovunque gira JavaScript: browser, Node.js, Deno.
TypeScript non sostituisce JavaScript: lo potenzia. Ogni file JavaScript valido è già TypeScript valido. Puoi adottarlo gradualmente nel tuo progetto esistente.
Perché usare TypeScript?
🐛 Errori a compile-time: individua i bug prima di eseguire il codice
🧠 Autocompletamento intelligente: l'editor conosce i tipi e suggerisce i metodi corretti
📖 Codice auto-documentato: i tipi spiegano cosa si aspetta ogni funzione
🔄 Refactoring sicuro: rinominare un campo aggiorna tutto il progetto
🏢 Standard industriale: usato da Google, Microsoft, Airbnb, Slack, VS Code stesso
📘 TypeScript non gira direttamente nel browser: viene compilato in JavaScript con il comando tsc. Usa il TypeScript Playground per provare subito senza installare nulla.
JS vs TS — stesso errore, esiti diversi
Get Started — Installazione
Per iniziare con TypeScript ti serve Node.js installato. TypeScript si installa globalmente via npm e si usa con il compilatore tsc.
Installazione e primo progetto
Avvio rapido senza installazione
Per sperimentare subito senza installare nulla, usa il TypeScript Playground ufficiale su typescriptlang.org/play: scrivi TypeScript a sinistra e vedi il JavaScript compilato a destra in tempo reale.
💡 Nei progetti moderni con Vite o Create React App, TypeScript è già configurato: basta usare l'estensione .ts o .tsx e il compilatore gira automaticamente in background.
Tipi semplici
TypeScript supporta tutti i tipi primitivi di JavaScript, con la possibilità di dichiararli esplicitamente. I principali tipi primitivi sono string, number, boolean.
Tipi primitivi
Tipo
Esempio
Descrizione
string
"ciao"
Testo
number
42, 3.14
Numeri interi e decimali
boolean
true, false
Valori logici
bigint
100n
Interi molto grandi
symbol
Symbol("id")
Identificatori unici
Dichiarazione esplicita e inferenza
TypeScript può dedurre (inferire) il tipo automaticamente dal valore assegnato. Non è sempre necessario scrivere il tipo esplicitamente: TypeScript lo capisce dal contesto.
Esplicito vs Inferito
💡 Regola pratica: lascia che TypeScript inferisca quando inizializzi con un valore. Dichiara esplicitamente quando la variabile è dichiarata senza valore o il tipo non è ovvio.
Tipi speciali
TypeScript ha alcuni tipi speciali che non esistono (o hanno significato diverso) in JavaScript puro.
any, unknown, never, void
Tipo
Uso
any
Disabilita il type checking — usare con parsimonia
unknown
Valore sconosciuto ma sicuro — richiede type guard prima dell'uso
void
Funzione senza valore di ritorno
never
Codice irraggiungibile o funzione che lancia sempre un errore
Array
Gli array TypeScript sono tipizzati: ogni elemento deve rispettare il tipo dichiarato. Ci sono due sintassi equivalenti per dichiarare un array tipizzato.
Array tipizzati
Tuple
Una tuple è un array con un numero fisso di elementi, ognuno con il proprio tipo. A differenza degli array normali, l'ordine e il tipo di ogni posizione sono definiti con precisione.
Tuple TypeScript
Object Types
TypeScript permette di descrivere la struttura degli oggetti definendo il tipo di ogni proprietà. Puoi usare la sintassi inline oppure un type alias o un'interfaccia.
Tipi degli oggetti
Enums
Un enum è un insieme di costanti con nome. Rendono il codice più leggibile rispetto ai valori magici come 0, 1, 2.
Enum numerici e a stringa
Type Aliases e Interfacce
Sia i type alias che le interfacce permettono di dare un nome a una struttura di tipo. Sono simili ma con differenze importanti.
Type Alias vs Interface
type
interface
Union / Intersection
✅
❌
Estensione
con &
con extends
Declaration merging
❌
✅
Classi (implements)
✅
✅
Union Types
Un union type permette a una variabile di avere uno tra più tipi possibili, separati dall'operatore |.
Union Types
Funzioni
TypeScript permette di tipizzare i parametri e il valore di ritorno delle funzioni, rendendo l'API di ogni funzione chiara e verificata a compile-time.
Funzioni tipizzate
Casting (Type Assertions)
Il casting in TypeScript permette di dire al compilatore "fidati, so il tipo di questo valore". Non converte il valore a runtime, ma dice al type checker come trattarlo.
Type assertions
⚠️ Il casting non converte il valore a runtime: se asserisci il tipo sbagliato, l'errore comparirà comunque durante l'esecuzione. Usare con cura.
Classi
TypeScript estende le classi ES6 con modificatori di accesso, proprietà tipizzate, classi astratte e molto altro.
Classi TypeScript
Generics base
I generics permettono di scrivere codice riutilizzabile che funziona con qualsiasi tipo, mantenendo la type-safety. Invece di usare any, usi un tipo parametro come T.
Funzioni e classi generiche
Utility Types
TypeScript include molti utility types predefiniti che trasformano un tipo esistente in uno nuovo. Evitano di riscrivere strutture simili da zero.
Utility Types più usati
Keyof
L'operatore keyof restituisce un union type con tutte le chiavi di un tipo oggetto. È molto utile per creare funzioni generiche che operano sulle proprietà di un oggetto.
keyof operator
Null e Undefined
Con strictNullChecks attivo (default in TypeScript moderno), null e undefined non sono assegnabili a qualsiasi tipo: devono essere esplicitamente dichiarati.
Gestione di null e undefined
Definitely Typed (@types)
Molte librerie JavaScript non includono i tipi TypeScript. Il progetto Definitely Typed fornisce i file di dichiarazione dei tipi (.d.ts) per migliaia di librerie populari, sotto il namespace @types.
Installare i tipi di una libreria
💡 Molte librerie moderne includono già i tipi (React, Axios, Zod, ecc.) — non serve installare @types separatamente. Controlla se esiste già un campo "types" in package.json.
TypeScript 5 — Novità principali
TypeScript 5 (2023) ha introdotto miglioramenti significativi alle performance e nuove funzionalità del linguaggio.
Novità TypeScript 5
Configurazione — tsconfig.json
Il file tsconfig.json controlla il comportamento del compilatore TypeScript per il progetto. È la prima cosa da configurare in ogni progetto TS.
tsconfig.json tipico
💡 Usa tsc --init per generare automaticamente un tsconfig.json di partenza con tutti i commenti esplicativi.
TypeScript con Node.js
TypeScript si integra perfettamente con Node.js. Per lo sviluppo locale puoi usare ts-node (esecuzione diretta) o tsx (più veloce). Per la produzione si compila con tsc.
Setup TypeScript + Node.js
TypeScript con React
React e TypeScript si abbinano perfettamente. Vite crea un progetto React+TypeScript con un solo comando. Le props, lo state e gli eventi sono tutti tipizzati.
Componente React tipizzato
Tooling
L'ecosistema TypeScript offre strumenti eccellenti per migliorare la produttività e la qualità del codice.
Strumento
Funzione
tsc
Compilatore ufficiale TypeScript
tsx / ts-node
Esecuzione diretta di file .ts senza compilazione
ESLint + @typescript-eslint
Linting e regole di qualità per TS
Prettier
Formattazione automatica del codice
Vite
Build tool moderno con supporto TS nativo
VS Code
L'IDE con il miglior supporto TypeScript (IntelliSense completo)
TypeScript Playground
Editor online ufficiale per sperimentare
Zod / Yup
Validazione runtime con inferenza dei tipi
Setup ESLint per TypeScript
Tipi avanzati
TypeScript offre operatori per costruire tipi complessi a partire da tipi esistenti: intersection, template literal types e molto altro.
Intersection, template literals, infer
Type Guards
I type guards sono controlli a runtime che permettono a TypeScript di restringere (narrowing) il tipo di una variabile all'interno di un blocco condizionale.
Type guards comuni
Tipi condizionali
I tipi condizionali permettono di scegliere un tipo in base a una condizione, usando la sintassi T extends U ? X : Y.
Conditional Types
Mapped Types
I mapped types creano un nuovo tipo iterando sulle chiavi di un tipo esistente. Sono la base su cui sono costruiti gli utility types come Partial, Readonly, Required.
Mapped Types
Inferenza dei tipi avanzata
TypeScript inferisce i tipi in molti contesti avanzati: valori di ritorno, parametri di callback, variabili distruttturate e altro ancora.
Inferenza avanzata
Literal Types
I literal types permettono di specificare non solo il tipo ma il valore esatto che una variabile può assumere. Sono molto usati per creare API espressive e sicure.
Literal Types
Namespaces
I namespaces (ex "moduli interni") organizzano il codice in scope nominati per evitare collisioni di nomi. Nei progetti moderni con ES Modules sono meno usati, ma restano utili per librerie e file di dichiarazione.
Namespaces
Index Signatures
Le index signatures permettono di definire il tipo dei valori di un oggetto quando le chiavi non sono note in anticipo (dizionari, mappe).
Index Signatures
Declaration Merging
TypeScript può unire più dichiarazioni con lo stesso nome in un'unica definizione. Funziona con interfacce, namespace e, in alcuni casi, funzioni.
Declaration Merging
Async Programming
TypeScript si integra perfettamente con Promise, async/await e i tipi asincroni. Tipizzare le Promise rende il codice asincrono più sicuro.
Promise e async/await tipizzati
Decorators
I decorators sono funzioni speciali che possono annotare e modificare classi, metodi, proprietà e parametri. Sono standard ECMAScript dalla versione TypeScript 5.
Decorators di classe e metodo
TypeScript in progetti JavaScript
Puoi usare TypeScript anche senza rinominare i file in .ts: attiva checkJs nel tsconfig e TypeScript controllerà i tuoi file JS esistenti con i commenti JSDoc.
TS in file .js con JSDoc
Migrazione da JavaScript a TypeScript
Migrare un progetto JS esistente a TypeScript è un processo graduale. Non è necessario convertire tutto in una volta.
Strategia di migrazione graduale
💡 Strategia consigliata: inizia abilitando TypeScript solo sui nuovi file, poi converti gradualmente i file esistenti partendo dai più semplici (tipi/utility) verso i più complessi (componenti principali).
Error Handling
TypeScript migliora la gestione degli errori tipizzando le eccezioni. Dal TS 4.4, puoi usare useUnknownInCatchVariables per forzare il controllo del tipo negli errori catturati.
Errori tipizzati
Best Practices TypeScript
Seguire le convenzioni della comunità TypeScript rende il codice più leggibile, manutenibile e sicuro.
Buone pratiche
🔒 Abilita sempre "strict": true nei nuovi progetti
🚫 Evita any — usa unknown e i type guard
📐 Preferisci interface per le API pubbliche e type per le union
🔑 Usa i discriminated union per gli stati complessi
🛠️ Configura ESLint con @typescript-eslint
📦 Organizza i tipi in file dedicati (types/ o *.types.ts)
Editor online — Prova TypeScript
TypeScript richiede compilazione prima dell'esecuzione. Usa questi strumenti per sperimentare subito senza installare nulla:
🎮 TypeScript Playground — Editor ufficiale: scrivi TS a sinistra, vedi il JS compilato a destra
🚀 StackBlitz — Ambiente Node.js o Vite completo nel browser
📘 L'editor integrato in questa pagina mostra il codice con la sintassi colorata e ti permette di modificarlo. Per eseguirlo usa uno dei link sopra.
Esercizi pratici TypeScript
Esercizio 1 — Tipizza un'interfaccia Prodotto
Crea un'interfaccia Prodotto con: id (number), nome (string), prezzo (number), categoria (union: "elettronica" | "abbigliamento" | "cibo"), sconto opzionale (number). Poi crea una funzione prezzoFinale(p: Prodotto): number.
Soluzione
Esercizio 2 — Funzione generica
Scrivi una funzione generica filtra<T>(array: T[], predicato: (item: T) => boolean): T[] che filtra un array mantenendo il tipo. Usala con array di numeri e array di oggetti.
Esercizio 3 — Utility Types
Dato un type Configurazione con 5 proprietà, crea con gli utility types: una versione con tutte opzionali, una senza password, una readonly.
Esercizio 4 — Classe con generics
Crea una classe generica Repository<T extends { id: number }> con metodi aggiungi, trovaPerId, rimuovi e tutti.
Quiz TypeScript
❓ Qual è la differenza tra any e unknown? R:any disabilita completamente il type checking; unknown richiede un type guard prima dell'uso — è la versione sicura di any.
❓ Quando preferire interface a type? R:interface quando definisci la forma di un oggetto o una classe (supporta extends e merging); type per union, intersection e tipi più complessi.
❓ Cosa fa Partial<T>? R: Rende tutte le proprietà di T opzionali (?). Utile per oggetti di aggiornamento parziale.
❓ Cos'è un type guard? R: Un controllo a runtime (typeof, instanceof, in) che permette a TypeScript di restringere il tipo di una variabile in un blocco condizionale.
❓ Cosa significa strict: true nel tsconfig? R: Abilita tutti i controlli rigorosi: strictNullChecks, noImplicitAny, strictFunctionTypes, ecc.
❓ Qual è la differenza tra un type alias e un'interfaccia per un union type? R: Solo type supporta i union type (string | number); le interfacce non possono esprimere direttamente un union.
Problemi pratici
Problema 1 — Sistema di notifiche
Crea un sistema di notifiche con un discriminated union Notifica (tipi: "info", "successo", "errore", "avviso") e una funzione che le visualizza in modo diverso.
Problema 2 — Validatore generico
Crea un tipo Validatore<T> con un metodo valida(val: unknown): val is T. Implementa validatori per string, number e oggetto Utente.
Problema 3 — Deep Readonly
Crea un utility type DeepReadonly<T> che rende readonly tutte le proprietà di T, incluse quelle annidate.
Soluzione DeepReadonly
Programma del corso TypeScript
Modulo
Argomenti
1 — Fondamenti
Intro, installazione, tipi primitivi, inferenza, tipi speciali
2 — Strutture
Array, tuple, object types, enums, type alias, interfacce
3 — Funzioni e classi
Union types, funzioni tipizzate, casting, classi, modificatori di accesso
tsconfig.json, Definitely Typed, TS con Node.js e React
7
Type guards, conditional types, mapped types, decorators
8
Best practices, migrazione, progetto completo tipizzato
💡 Se già conosci JavaScript, 4 settimane bastano per i moduli 1-5. Concentra le ultime settimane sui generics e la configurazione — sono le basi per usare TS in progetti reali.
Domande da colloquio TypeScript
💬 Cos'è TypeScript e qual è il suo rapporto con JavaScript? — TypeScript è un superset di JavaScript con tipizzazione statica opzionale. Ogni codice JS è TS valido; TS viene compilato in JS prima dell'esecuzione.
💬 Differenza tra interface e type? — Entrambi descrivono strutture di oggetti. interface supporta declaration merging ed è preferita per le API; type supporta union, intersection e tipi complessi.
💬 Cosa sono i generics e perché usarli? — Permettono di scrivere codice riutilizzabile che mantiene la type-safety con qualsiasi tipo, senza ricorrere ad any.
💬 Cosa fa strict: true? — Abilita strictNullChecks, noImplicitAny, strictFunctionTypes e altri controlli rigorosi. Fortemente consigliato in tutti i nuovi progetti.
💬 Differenza tra unknown e any? — any disabilita il type checking; unknown è sicuro perché richiede un type guard prima di operare sul valore.
💬 Cosa sono i discriminated union? — Union di oggetti con un campo discriminante comune (es. tipo: "A" | "B") che permette a TypeScript di narroware il tipo automaticamente con switch/if.
💬 Come tipizzare le props in React con TypeScript? — Con un'interfaccia o type alias passato come generic al componente o usato nel destructuring dei parametri della funzione.
Bootcamp TypeScript — Progetto finale
Costruisci un'app completamente tipizzata che integra tutto il corso:
🚀 Progetto: API Client tipizzato + Dashboard React
🔷 Tipi condivisi: definisci in types/ tutte le interfacce (Utente, Prodotto, Ordine, ApiResponse)
🔌 API Client generico: classe generica ApiClient<T> con metodi get, post, put, delete tutti tipizzati
🗂️ Repository pattern: Repository<T extends { id: number }> con CRUD completo
🛡️ Error handling: classi di errori custom, gestione type-safe negli async
✅ Strict mode: zero any, zero @ts-ignore, strict: true
🎯 Sfida avanzata
Implementa un validatore generico usando i mapped types e i conditional types: dato uno schema di validazione, crea automaticamente il tipo TypeScript corrispondente (simile a ciò che fa la libreria Zod).
Certificazione TypeScript
TypeScript è richiesto in quasi tutte le posizioni frontend/fullstack moderne. Ecco come valorizzare le tue competenze:
Certificazione / Percorso
Ente
Note
TypeScript Certificate
W3Schools
Base, buono per il CV
Meta Front-End Developer
Coursera (Meta)
Include TypeScript + React
TypeScript: The Complete Course
Udemy
Certificato di completamento
Execute Program — TypeScript
Execute Program
Corso interattivo, molto pratico
Total TypeScript
Matt Pocock
Il corso più avanzato disponibile
Progetto su GitHub
Portfolio
La migliore prova pratica per i recruiter
Come prepararsi al colloquio TS
🔷 Conosci bene generics, utility types e mapped types
🏗️ Mostra un progetto React+TypeScript con zero any
📖 Studia i tipi avanzati (conditional, template literal, infer)
🔧 Sai configurare il tsconfig e lavorare con @types
🛡️ Conosci i pattern per gestire unknown e i discriminated union
Conclusione — E ora?
Hai completato il corso TypeScript! Hai imparato i tipi primitivi, l'inferenza, i tipi speciali, array, tuple, enums, interfacce, union types, generics, utility types, classi, decorators, mapped types, conditional types, type guards, la configurazione con tsconfig e l'integrazione con Node.js e React.
I tuoi prossimi passi
⚛️ Usa TypeScript nel tuo prossimo progetto React: è il modo più rapido per consolidare le basi
📦 Studia Zod: validazione runtime con inferenza automatica dei tipi TS
🚀 Esplora Next.js con TypeScript: routing, server components, API routes tutti tipizzati
🎓 Segui Total TypeScript di Matt Pocock per i tipi avanzati
🔧 Configura ESLint + @typescript-eslint nel tuo progetto per mantenere alta la qualità
🏗️ Contribuisci a DefinitelyTyped: aggiungi i tipi a una libreria che usi
🎯 La tua sfida finale
Prendi un tuo progetto JavaScript esistente (o uno degli esercizi dei corsi precedenti) e migra almeno il 50% del codice a TypeScript con strict mode attivo e zero any. Documenta i bug che TypeScript ha trovato durante la migrazione — scoprirai che il compilatore cattura problemi reali che il runtime non avrebbe segnalato subito.