Menu

TypeScript vs JavaScript: differenze principali con esempi

TypeScript è JavaScript con in più un sistema di tipi statico, controllato prima che il codice venga eseguito. Confronta i due fianco a fianco: sintassi, cosa intercetta il type checker, il passaggio di build, velocità a runtime, curva di apprendimento e come migrare un progetto JavaScript.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

TypeScript è JavaScript con un sistema di tipi statico aggiunto sopra. Ogni programma JavaScript è sintassi TypeScript valida; TypeScript aggiunge le annotazioni di tipo, un compilatore che le controlla prima che il codice venga eseguito e un passaggio di build che le rimuove di nuovo. A runtime c'è solo JavaScript, quindi la differenza sta tutta in ciò che scopri prima di pubblicare.

In JavaScript la stessa funzione è il codice senza type Product = ..., : Product[] e : number. I tipi aggiungono informazioni per il compilatore e per l'editor; non cambiano ciò che fa il programma.

TypeScript vs JavaScript a colpo d'occhio

JavaScriptTypeScript
Sistema di tipiDinamico: i tipi appartengono ai valori e si conoscono solo a runtimeStatico: i tipi sono dichiarati o dedotti e controllati in fase di compilazione
Quando emergono gli errori di tipoQuando la riga viene eseguita (undefined, NaN, TypeError)Nell'editor mentre scrivi, e quando compili
Gira inBrowser, Node.js, Deno, Bun, direttamenteGli stessi ambienti, dopo la rimozione dei tipi
Passaggio di buildNon servetsc o un bundler, oppure un runtime che rimuove i tipi da solo
File.js, .mjs, .cjs.ts, .mts, .cts, .tsx, più le dichiarazioni di tipo .d.ts
Velocità a runtimeRiferimentoIdentica: l'output è JavaScript
Supporto dell'editorAutocompletamento dai tipi dedotti e dai typing delle librerie, che possono essere incompletiAutocompletamento, rinomina e "trova tutti i riferimenti" dai tipi dichiarati
Curva di apprendimentoPiù bassaJavaScript più il sistema di tipi
StandardECMAScript, di TC39Un progetto open source di Microsoft che segue ECMAScript

Lo stesso codice nei due linguaggi

Ecco una funzione in JavaScript. Niente al suo interno dice come deve essere fatto user:

function greeting(user) {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// "Hello, undefined Lovelace", no error anywhere

La versione TypeScript dichiara la forma una volta, e l'errore di battitura viene segnalato prima che il codice venga eseguito:

interface User {
    firstName: string;
    lastName: string;
}

function greeting(user: User): string {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// error TS2561: Object literal may only specify known properties,
// but 'firstname' does not exist in type 'User'. Did you mean to write 'firstName'?

Le annotazioni sono l'intera differenza di sintassi. TypeScript aggiunge anche alcune dichiarazioni proprie (interface, type, enum, generics come Array<string>, modificatori di accesso come private), ma istruzioni, operatori e oggetti integrati sono quelli di JavaScript.

Cosa intercetta TypeScript e JavaScript no

JavaScript converte i tipi in silenzio. Questo bug è comune con i valori che arrivano dai campi di un form, che sono sempre stringhe. Eseguilo per vedere cosa dice il compilatore:

index.ts(7,17): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
  Type 'string' is not assignable to type 'number'.

In JavaScript questo codice viene eseguito e stampa 010205, perché 0 + "10" è una concatenazione di stringhe. TypeScript si rifiuta di compilare finché le stringhe non vengono convertite, per esempio con fromForm.map(Number).

L'altra grande categoria sono i valori che potrebbero mancare. Array.prototype.find restituisce undefined quando nessun elemento corrisponde, e TypeScript ti obbliga a gestire il caso:

index.ts(8,13): error TS18048: 'user' is possibly 'undefined'.

La versione in semplice JavaScript va in crash a runtime con TypeError: Cannot read properties of undefined (reading 'name'). La soluzione in TypeScript è gestire il caso indicato dal compilatore:

Output:

GRACE
no user with id 3

Cosa TypeScript non intercetta: gli errori di logica (una formula sbagliata ha il tipo giusto) e tutto ciò che riguarda i dati che entrano nel programma a runtime. Una risposta di un'API tipizzata come User è corretta solo quanto il server che l'ha inviata, perché i tipi spariscono quando il codice viene eseguito. Controlla questi dati con codice a runtime.

Usare librerie JavaScript in TypeScript

Ogni pacchetto npm funziona da TypeScript, perché l'output è comunque JavaScript. I tipi di un pacchetto arrivano da uno di tre posti:

  • Il pacchetto include i propri file .d.ts. La maggior parte dei pacchetti mantenuti attivamente lo fa, e non devi installare nient'altro.
  • Un pacchetto @types separato del progetto comunitario DefinitelyTyped: npm install --save-dev @types/lodash aggiunge i tipi per lodash.
  • Da nessuna parte. In quel caso, con strict attivo, l'import stesso è un errore:
error TS7016: Could not find a declaration file for module 'lodash'. '/project/node_modules/lodash/lodash.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/lodash` if it exists or add a new declaration (.d.ts) file containing `declare module 'lodash';`

La soluzione è installare il pacchetto @types, se esiste, oppure descrivere tu il modulo in un file .d.ts; la pagina sui declaration file mostra come.

Il passaggio di build

Browser e Node.js non controllano i tipi, quindi TypeScript ha bisogno di un passaggio tra il tuo sorgente e il codice che viene eseguito. Ci sono tre configurazioni comuni:

  • tsc compila tutto. Controlla i tipi e scrive i file .js, di solito in una cartella dist. Semplice, ed è lo standard per le librerie.
  • Un bundler o un dev server rimuove i tipi, e tsc --noEmit li controlla. Vite ed esbuild eliminano i tipi senza controllarli, così i ricaricamenti restano rapidi; il type checker lo eseguono l'editor e un passaggio della CI.
  • Il runtime rimuove i tipi. Le versioni attuali di Node.js, Deno e Bun eseguono direttamente i file .ts. Nessuno di loro controlla i tipi durante l'esecuzione, quindi tsc --noEmit (o deno check) resta il modo per trovare gli errori di tipo.

JavaScript non ha bisogno di nulla di tutto questo, ed è il suo vantaggio pratico più grande per gli script piccoli. Il costo del passaggio TypeScript è soprattutto la configurazione, un tsconfig.json e una dipendenza di sviluppo typescript, più il tempo di compilazione; il compilatore nativo di TypeScript 7 ha ridotto quel tempo di circa dieci volte sui progetti grandi.

Curva di apprendimento

Tutto ciò che sai di JavaScript resta valido, perché il runtime di TypeScript è JavaScript. La parte nuova è il sistema di tipi, e si impara a livelli:

  1. Annotazioni su variabili, parametri e valori di ritorno (: string, : number[]).
  2. Tipi oggetto con interface e type, proprietà opzionali, union come string | number.
  3. Narrowing: controllare un valore con typeof, in o === in modo che il compilatore sappia in quale caso ti trovi.
  4. Generics, utility type come Partial<T> e Pick<T, K>, e tipi avanzati per chi scrive librerie.

I primi due livelli coprono la maggior parte del codice applicativo. Buona parte dei tipi viene dedotta, quindi molto codice TypeScript sembra JavaScript con annotazioni solo sulle firme delle funzioni.

Quando scegliere TypeScript o JavaScript

TypeScript è meglio di JavaScript? Per il codice mantenuto da più persone o che dura anni, di solito sì, e il settore si è mosso in quella direzione: secondo il conteggio dei contributori mensili di GitHub, ad agosto 2025 TypeScript ha superato sia JavaScript sia Python diventando il linguaggio più usato su GitHub. Per gli script piccoli, il semplice JavaScript è spesso lo strumento migliore.

Scegli TypeScript quando:

  • Sul codice lavora più di una persona, o verrà mantenuto per mesi o anni.
  • La codebase è abbastanza grande da non poter tenere a mente tutte le firme delle funzioni.
  • Fai refactoring spesso: rinominare una proprietà aggiorna ogni suo uso, e il compilatore elenca tutto ciò che resta indietro.
  • Pubblichi una libreria: i file .d.ts danno a chi la usa autocompletamento e controlli.
  • Il framework se lo aspetta. Le app Angular si scrivono in TypeScript, Next.js e Astro creano i nuovi progetti in TypeScript di default, e i template React, Vue e Svelte di Vite hanno ciascuno una variante TypeScript.

Scegli JavaScript quando:

  • Il programma è uno script breve, un esperimento occasionale o un frammento di codice nella console del browser.
  • Stai imparando a programmare per la prima volta e vuoi meno concetti tutti insieme.
  • Non c'è un passaggio di build e non ne vuoi uno. Anche in quel caso, // @ts-check con JSDoc ti dà qualche controllo in un semplice file .js.

Migrare un progetto JavaScript a TypeScript

Una migrazione non deve avvenire tutta in una volta. Il compilatore accetta JavaScript accanto a TypeScript:

{
    "compilerOptions": {
        "allowJs": true,
        "checkJs": false,
        "outDir": "dist",
        "rootDir": "src"
    },
    "include": ["src"]
}

Con allowJs, i file .js vengono compilati e possono importare dai file .ts e viceversa. Poi converti un po' alla volta:

  1. Rinomina un file da .js a .ts e correggi gli errori che il compilatore segnala al suo interno.
  2. Parti dalle foglie (moduli di utilità con pochi import), poi procedi verso l'interno.
  3. Attiva checkJs, o aggiungi // @ts-check in cima ai singoli file .js, per controllare i tipi dei file che non hai ancora rinominato.

Nei file JavaScript controllati, i tipi li forniscono i commenti JSDoc:

// @ts-check

/**
 * @param {number} price
 * @param {number} qty
 * @returns {number}
 */
function lineTotal(price, qty) {
    return price * qty;
}

lineTotal("3", 2);
// error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Alcuni team si fermano qui: file JavaScript con tipi JSDoc, controllati da tsc, e nessun passaggio di build per il codice stesso. Altri arrivano fino a .ts. Se attivi strict in un progetto esistente, aspettati molti errori all'inizio; la pagina sullo strict mode elenca cosa controlla ogni flag, così puoi attivarli uno alla volta.

Domande frequenti

Qual è la differenza principale tra TypeScript e JavaScript?

TypeScript aggiunge i tipi statici a JavaScript. Descrivi cos'è ogni valore (name: string, items: Item[]) e il compilatore TypeScript segnala gli errori prima che il codice venga eseguito. JavaScript non controlla nulla in anticipo: un tipo sbagliato emerge solo quando quella riga viene eseguita, spesso come undefined o come TypeError.

TypeScript è meglio di JavaScript?

Per la maggior parte dei progetti mantenuti da più di una persona, o che durano più di qualche settimana, sì: i tipi intercettano intere categorie di bug, rendono sicuro il refactoring e alimentano l'autocompletamento dell'editor. Per uno script breve, un prototipo veloce o un esercizio di apprendimento, il semplice JavaScript è più rapido da avviare e non richiede alcuna configurazione di build.

TypeScript è più veloce di JavaScript?

No, e non è nemmeno più lento. TypeScript viene compilato in JavaScript e i tipi vengono eliminati, quindi il codice eseguito è lo stesso JavaScript che scriveresti a mano. L'unico costo in più è il tempo di compilazione durante lo sviluppo.

Devo imparare prima JavaScript o TypeScript?

Impara le basi di JavaScript prima di TypeScript o insieme a esso. Tutto il comportamento a runtime (variabili, funzioni, oggetti, array, promise) è JavaScript, e TypeScript si limita a descriverlo. Quando sai scrivere piccoli programmi in JavaScript, aggiungere i tipi è un passo breve.

Posso usare TypeScript e JavaScript nello stesso progetto?

Sì. Imposta "allowJs": true in tsconfig.json e il compilatore accetta file .js accanto ai file .ts. Aggiungi "checkJs": true (o un commento // @ts-check per file) per controllare i tipi anche nei file JavaScript, usando i tipi dei commenti JSDoc. È il modo abituale per migrare un progetto un file alla volta.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA