Documentazione TypeScript
Guida di riferimento a TypeScript concisa e ricca di esempi. Leggi il concetto, guarda il codice e poi mettilo in pratica in un percorso Coddy.
Inizia un percorso guidato di TypeScriptPrimi passi
- Cos'è TypeScriptTypeScript è JavaScript con i tipi statici. Annoti i valori con i tipi, il compilatore li controlla prima che il codice venga eseguito e il risultato è JavaScript normale, che funziona in qualsiasi browser e in Node.js, Deno e Bun.
- TypeScript vs JavaScriptTypeScript è 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.
- Installare TypeScriptInstalla TypeScript con npm come dev dependency del progetto, controlla la versione con npx tsc --version, crea un tsconfig.json con tsc --init e compila il tuo primo file. Vedremo installazioni globali, pnpm, Yarn e Bun, e gli errori più frequenti.
- Eseguire TypeScriptCinque modi per eseguire un file .ts: compilare con tsc ed eseguire il JavaScript, eseguirlo direttamente con node file.ts (type stripping), usare tsx o ts-node, oppure usare Deno e Bun. Quali controllano i tipi, quale sintassi supporta ciascuno e quale scegliere.
- tsconfig.jsontsconfig.json indica che una cartella è un progetto TypeScript e imposta le opzioni del compilatore. Le opzioni che contano (target, module, moduleResolution, strict, rootDir, outDir, include, lib, types, noEmit, skipLibCheck), una configurazione iniziale consigliata, extends e cosa è cambiato in TypeScript 7.
- TypeScript 7TypeScript 7 è il compilatore TypeScript riscritto in Go come programma nativo: circa dieci volte più veloce, con lo stesso comando tsc e lo stesso linguaggio. Cosa cambia per chi lo usa (nuovi valori predefiniti, opzioni rimosse, l'API JavaScript mancante), quali strumenti richiedono ancora TypeScript 6 e come aggiornare.
- CommentiTypeScript usa i commenti // e /* */ di JavaScript, più i commenti JSDoc /** */ che gli editor mostrano al passaggio del mouse. Legge anche alcuni commenti speciali: @ts-expect-error, @ts-ignore, @ts-nocheck, @ts-check e le direttive /// <reference>.
- TypeScript vs PythonTypeScript e Python sono entrambi linguaggi di alto livello con garbage collection, ma TypeScript controlla i tipi prima che il codice venga eseguito, mentre i type hint di Python sono facoltativi e a runtime vengono ignorati. Un confronto fianco a fianco su tipi, runtime, velocità, ecosistemi e casi d'uso, con lo stesso programma nei due linguaggi.
Tipi di base
- Tipi di baseI tipi predefiniti di TypeScript: string, number, boolean, bigint, symbol, null e undefined, più array e oggetti in breve. Come si scrive un'annotazione di tipo, perché non esiste un tipo intero e perché si scrive string invece di String.
- Type inferenceTypeScript ricava la maggior parte dei tipi dai valori che scrivi. Scopri cosa deduce per variabili, let e const, oggetti, array e valori di ritorno, come le callback ricevono i tipi dal contesto e dove serve ancora un'annotazione.
- StringheLavorare con le stringhe in TypeScript: interpolazione con i template literal, stringhe su più righe, verificare se una stringa contiene una sottostringa, i metodi più comuni con i tipi che restituiscono e i tipi letterali stringa.
- Da stringa a numeroConverti una stringa in numero in TypeScript con Number(), parseInt(), parseFloat() o il + unario, guarda come ciascuno gestisce input come "42px", "" e "1e3", controlla NaN in modo sicuro e riconverti i numeri in stringhe.
- ArrayCome tipizzare gli array in TypeScript: T[] vs Array<T>, array di oggetti, array con più tipi, array readonly e cosa restituiscono map, filter, reduce e find. In più la trappola di includes con gli array di letterali.
- TupleUna tuple in TypeScript è un array con un numero fisso di elementi il cui tipo è noto per posizione, come [string, number]. Scopri la sintassi, gli elementi con nome, opzionali e rest, le tuple readonly e as const, come restituire tuple dalle funzioni e in cosa differiscono dagli array.
- Tipi oggettoCome tipizzare gli oggetti in TypeScript: tipi oggetto inline, proprietà opzionali con ?, proprietà readonly, oggetti annidati, metodi, il controllo delle proprietà in eccesso e la differenza tra object, {} e Object.
- EnumUn enum TypeScript è un insieme di costanti con nome, come enum Direction { Up, Down }. Scopri gli enum numerici e di stringhe, il JavaScript in cui viene compilato un enum, la mappatura inversa, come iterare su un enum, i const enum e quando una union di letterali stringa o un oggetto as const è la scelta migliore.
Tipi speciali
- Literal typesUn literal type è un tipo con un solo valore, come "GET" o 404. Scopri i literal types di stringhe, numeri e booleani, le unioni di letterali, perché let allarga il tipo e const no, cosa fa as const, e i const type parameters.
- any vs unknownSia any sia unknown accettano qualsiasi valore. any disattiva il controllo dei tipi per quel valore, mentre unknown ti obbliga a verificarlo prima di usarlo. Scopri le differenze, come restringere unknown, noImplicitAny e dove any si infila nel codice tipizzato.
- Tipo nevernever è il tipo senza valori. È il tipo di ritorno delle funzioni che non finiscono mai, il tipo che resta quando il narrowing ha escluso ogni caso e lo strumento dietro i controlli esaustivi negli switch. Scopri da dove viene e in cosa si distingue da void.
- null e undefinedCon strictNullChecks, null e undefined sono tipi separati che TypeScript ti obbliga a gestire. Scopri come controllarli, l'optional chaining (?.), il doppio punto interrogativo (??) e ??=, e la differenza tra una proprietà opzionale e | undefined.
- Non-null assertion (!)Un punto esclamativo dopo un valore, come user!, è l'operatore di non-null assertion: toglie null e undefined dal tipo senza alcun controllo a runtime. Scopri cosa fa x!, le forme di definite assignment let x!: T e prop!: T, perché sono rischiose e le alternative più sicure.
Interfacce e alias di tipo
- InterfaceUn'interfaccia dà un nome alla forma di un oggetto: quali proprietà ha e di che tipo sono. Scopri come dichiararne una, proprietà opzionali e readonly, metodi, index signature, estensione, implementazione in una classe, declaration merging, interfacce generiche e come dare valori predefiniti a un'interfaccia.
- Type aliasUn type alias dà un nome a qualsiasi tipo con la parola chiave type: forme di oggetti, union, tuple, funzioni, generics e tipi ricorsivi. Scopri la sintassi, come appare ogni forma e perché un alias è solo un nome e non un tipo nuovo e distinto.
- Interface vs typeinterface e type possono entrambi descrivere forme di oggetti, e quasi sempre vanno bene tutti e due. Scopri le differenze reali: declaration merging, unioni e mapped types, extends e intersezioni, index signature implicite, messaggi di errore e prestazioni del compilatore, più una regola chiara per scegliere.
- Parola chiave extendsLa parola chiave extends costruisce un tipo a partire da un altro. Scopri come estendere un'interfaccia (una o più), estendere un alias di tipo con &, ridefinire il tipo di una proprietà, sostituire proprietà con Omit, e cosa significa extends nelle classi, nei vincoli generici e nei conditional types.
- Union typesUn union type come string | number indica che un valore può essere uno qualsiasi tra più tipi. Scopri cosa puoi fare con una union (solo ciò che supportano tutti i membri), come restringerla, le union di letterali e di tipi oggetto e la differenza tra (A | B)[] e A[] | B[].
- Intersection typesUn intersection type A & B descrive un valore che è allo stesso tempo A e B, quindi ha tutti i membri di entrambi. Scopri come combinare tipi oggetto con &, perché le proprietà in conflitto diventano never, perché le intersezioni di unioni tengono solo i membri comuni, e quando usare invece extends.
- Discriminated unionUna discriminated union è una union di tipi oggetto che condividono una proprietà tag letterale, come kind o status. Controllare il tag restringe l'intero oggetto. Scopri il pattern, il restringimento con switch, i controlli di esaustività con never e come modellare risultati di API, stato delle richieste e macchine a stati.
Funzioni
- FunzioniCome tipizzare le funzioni in TypeScript: annota ogni parametro, annota o lascia dedurre il tipo di ritorno, usa void per le funzioni che non restituiscono nulla, e tipizza arrow function, function expression, funzioni async e il parametro this.
- Tipi funzioneCome scrivere il tipo di una funzione in TypeScript: la sintassi a freccia (a: number) => string, gli alias di tipo per le funzioni, come tipizzare arrow function e callback, call signature e construct signature, e perché il tipo Function è troppo permissivo.
- Parametri opzionaliRendi opzionale un parametro TypeScript con ?, dagli un valore predefinito o raccogli un numero qualsiasi di argomenti con un parametro rest. Include le regole sull'ordine, omesso vs undefined, oggetti di opzioni e parametri opzionali nei tipi di funzione.
- Overloading di funzioniGli overload di funzione in TypeScript permettono a una funzione di avere più firme di chiamata, ciascuna con il suo tipo di ritorno. Impara lo schema overload signatures più implementazione, le regole che controlla il compilatore, quando conviene un parametro unione e gli overload nelle classi.
Narrowing e controllo dei tipi
- Type narrowingIl narrowing è il modo in cui TypeScript trasforma un tipo ampio come string | number in uno specifico dentro un if, uno switch o dopo un return anticipato. Tutte le forme di narrowing in un unico posto: typeof, truthiness, uguaglianza, in, instanceof, assegnazioni, type predicate e discriminated union.
- Operatore typeofIn TypeScript typeof ha due compiti. Nel codice è l'operatore JavaScript che a runtime restituisce "string", "number", "object" e così via, e TypeScript restringe il tipo in base a esso. In un tipo è la type query che copia il tipo di una variabile, come in keyof typeof obj e ReturnType<typeof fn>.
- Operatore instanceofinstanceof controlla a runtime se un oggetto è stato creato da una classe, e TypeScript restringe la variabile a quella classe. Come funziona con le tue classi e con le sottoclassi di Error, perché non può controllare interfacce o alias di tipo, e dove dà risposte sorprendenti.
- Type guardUn type guard è un controllo a runtime che TypeScript capisce. Scopri i guard integrati, come scriverne uno tuo con un predicato value is Type, come verificare se un oggetto è di un certo tipo, le assertion function con asserts e come validare dati unknown.
- Type assertionLa parola chiave as dice a TypeScript di trattare un valore come se avesse un altro tipo. Non è un cast: a runtime non viene convertito né controllato nulla. Scopri la sintassi con as e con le parentesi angolari, cosa permette il compilatore, le doppie asserzioni tramite unknown e quando un type guard è lo strumento migliore.
- Operatore satisfiesL'operatore satisfies controlla che un valore corrisponda a un tipo senza cambiare il tipo inferito del valore. Scopri cosa fa, come si confronta con un'annotazione di tipo e con as (lo stesso oggetto scritto in tre modi), come si combina con as const e perché è adatto agli oggetti di configurazione.
Classi
- ClassiLe classi TypeScript sono classi JavaScript con campi, metodi e costruttori tipizzati. Scopri come funzionano le dichiarazioni dei campi e strictPropertyInitialization, come tipizzare this, getter e setter, membri statici, implements e perché una classe vale anche come tipo.
- CostruttoriCome tipizzare il costruttore di una classe in TypeScript: parametri tipizzati e facoltativi, parameter property come constructor(private name: string), ordine di inizializzazione dei campi, overload del costruttore, chiamate a super nelle sottoclassi, costruttori privati e tipi costruttore con new.
- Modificatori di accessoTypeScript ha tre modificatori di accesso, public, private e protected, più readonly. Scopri cosa consente ciascuno, perché private di TypeScript è un controllo in compilazione mentre i campi #private di JavaScript vengono imposti a runtime, e quale scegliere.
- EreditarietàL'ereditarietà delle classi in TypeScript: extends e super, override dei metodi con tipi compatibili, la parola chiave override e noImplicitOverride, i membri protected, come ridichiarare campi con declare e quando implements è lo strumento migliore.
- Classi astratteUna classe astratta in TypeScript è una classe base che non si può istanziare e che può lasciare dei metodi da implementare alle sottoclassi. Scopri metodi e proprietà astratti, il pattern template method, i tipi di costruttore astratti e quando conviene di più un'interfaccia.
- DecoratorI decorator sono funzioni che avvolgono o sostituiscono i membri di una classe con la sintassi @. Scopri i decorator standard che TypeScript supporta senza alcun flag (classe, metodo, getter, campo e accessor), le decorator factory, addInitializer e in cosa differiscono dai vecchi experimentalDecorators usati da Angular e NestJS.
Generics
- GenericsI generics permettono a una funzione, interfaccia, tipo o classe di lavorare con molti tipi mantenendoli collegati: ciò che entra decide ciò che esce. Impara le funzioni generiche, la deduzione degli argomenti di tipo, più parametri di tipo, interfacce e classi generiche, i default e quando non usare i generics.
- Vincoli genericiUn vincolo generico, T extends Something, limita i tipi che un parametro di tipo accetta e permette alla funzione di usare ciò che il vincolo garantisce. Vedremo extends con forme di oggetti e interfacce, K extends keyof T per accedere alle proprietà in sicurezza, vincoli sui primitivi e gli errori che incontrerai.
Operatori di tipo
- Operatore keyofkeyof prende un tipo oggetto e ti dà l'unione dei nomi delle sue proprietà. Scopri keyof con le interfacce, keyof typeof per gli oggetti semplici, l'accesso tipizzato alle proprietà con i generics, le index signature (string | number), e perché Object.keys restituisce string[].
- Indexed access typesUn indexed access type legge il tipo di una proprietà da un altro tipo: Person["age"] è number. Impara T["key"], le chiavi unione, T[keyof T], T[number] per gli elementi di un array, gli indici delle tuple e (typeof arr)[number] per trasformare un array const in un'unione.
- Mapped typesUn mapped type costruisce un nuovo tipo oggetto scorrendo delle chiavi: { [K in keyof T]: ... }. Impara la sintassi, i modificatori readonly e ? con + e -, la rimappatura delle chiavi con as, come filtrare le chiavi e come sono scritti Partial, Readonly, Required, Pick e Record.
- Tipi condizionaliUn tipo condizionale sceglie uno tra due tipi in base a un test: T extends U ? X : Y. Scopri la sintassi, come i tipi condizionali si distribuiscono sulle union (e come impedirlo), come estrarre tipi con infer e come scrivere ReturnType da solo.
- Template literal typesI template literal types costruiscono tipi letterali stringa con la stessa sintassi a backtick delle template string di JavaScript: `on${Capitalize<E>}`. Impara la sintassi, come si moltiplicano le union, Uppercase e Capitalize, pattern come `${number}px`, getter con i mapped type e il parsing di stringhe con infer.
- Branded typeUn branded type è un primitivo con un'etichetta invisibile, come string & { readonly __brand: "UserId" }, così un UserId non può essere passato dove è atteso un OrderId. Scopri come funzionano i brand, le funzioni costruttrici che validano, un helper Brand generico, i brand con unique symbol e i numeri con brand.
Utility type
- Utility typesTutti gli utility types integrati di TypeScript in un unico posto: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, i tipi per le stringhe e altri, ognuno con una descrizione di una riga e un esempio eseguibile.
- RecordRecord<K, V> è il tipo oggetto le cui chiavi sono K e i cui valori sono tutti V. Impara Record con chiavi string e con chiavi in unione (tutte obbligatorie), Partial<Record>, come iterare su un Record con chiavi tipizzate, il problema della chiave mancante e quando usare una index signature o una Map.
- Partial e RequiredPartial<T> rende opzionali tutte le proprietà di T, ed è proprio il tipo di un oggetto di aggiornamento o patch. Impara Partial nelle funzioni di aggiornamento, perché è superficiale, come scrivere un DeepPartial, il problema dell'undefined esplicito e il suo opposto, Required<T>.
- OmitOmit<T, K> crea un tipo con tutte le proprietà di T tranne le chiavi K. Impara Omit con una e più chiavi, come sovrascrivere il tipo di una proprietà, come rimuovere la proprietà in fase di esecuzione, Omit vs Exclude e Pick, perché Omit accetta chiavi che non esistono, un Omit rigoroso e Omit sui tipi unione.
- PickPick<T, K> crea un tipo con le sole proprietà di T le cui chiavi sono in K. Impara Pick con una o più chiavi, come controlla le chiavi, Pick vs Omit, come selezionare da tipi annidati, una funzione pick() tipizzata e come selezionare proprietà in base al tipo del loro valore.
- readonly e ReadonlyIl modificatore readonly e l'utility type Readonly<T> impediscono al codice di riassegnare le proprietà. Impara le proprietà readonly e i campi di classe, Readonly<T>, gli array readonly (readonly T[] e ReadonlyArray), ReadonlyMap e ReadonlySet, perché readonly è superficiale e vale solo in compilazione, e come si confronta con Object.freeze e as const.
- Exclude ed ExtractExclude, Extract e NonNullable filtrano i membri di un tipo union. Scopri cosa tiene e cosa rimuove ciascuno, come scegliere i membri di una union in base alla forma, come sono costruiti a partire dai tipi condizionali e in cosa differiscono da Omit e Pick.
- ReturnType e ParametersReturnType, Parameters, ConstructorParameters, InstanceType e Awaited estraggono tipi da funzioni, classi e promise. Impara a usarli con typeof, come ottenere il tipo del risultato di una funzione async, cosa succede con overload e generici, e come ReturnType è costruito con infer.
Cicli e collezioni
- CicliTutti i modi di scrivere un ciclo in TypeScript e i tipi che ti dà ciascuno: il classico ciclo for, for...of su array, map e stringhe, for...in e le sue chiavi stringa, forEach (niente break, niente await), cicli tipizzati sulle chiavi di un oggetto, e while.
- Istruzione switchL'istruzione switch in TypeScript: sintassi, come ogni case restringe un tipo union, switch esaustivi che non compilano quando manca un case, il pattern switch (true), il fallthrough e lo scope dei blocchi.
- MapCome usare Map in TypeScript: creare un Map<K, V> tipizzato, perché get restituisce V | undefined, set, has e delete, iterare in ordine di inserimento, chiavi oggetto, conversione da e verso oggetti e JSON, Map vs oggetto vs Record, e come tipizzare array.map().
- DizionarioTypeScript non ha una classe dizionario o hashmap; tipizzi una tabella chiave-valore con una index signature, con Record<K, V> o con Map<K, V>. Scopri ciascuna, come verificare se una chiave esiste, aggiungere, eliminare e iterare, e perché noUncheckedIndexedAccess conta per i dizionari.
Asincronia ed errori
- PromiseCome si tipizzano le promise in TypeScript: il tipo Promise<T>, tipizzare new Promise e resolve, come then cambia il tipo, perché catch ti dà any, Promise.all con risultati in tupla, i tipi dei risultati di Promise.allSettled e come avvolgere API a callback in una promise tipizzata.
- Async/AwaitCome si tipizzano async e await in TypeScript: una funzione async restituisce Promise<T>, await la scarta, gli errori si catturano con try/catch, l'await top-level richiede un modulo ES, e la differenza tra attendere uno alla volta, attendere in parallelo e la trappola di forEach.
- Gestione degli erroriLa gestione degli errori in TypeScript: perché la variabile del catch è unknown, come restringerla con instanceof Error, lanciare errori, scrivere classi di errore personalizzate con name e cause, e il pattern del tipo Result per gli errori che ti aspetti.
- SleepTypeScript non ha uno sleep integrato, ma basta una riga per averne uno: una funzione che restituisce una Promise<void> risolta da setTimeout. Impara ad attenderla con await, a fare pause dentro i cicli, a riprovare con un ritardo, a cancellare uno sleep e perché JavaScript non ha uno sleep bloccante.
Moduli e strumenti
- ModuliOgni file TypeScript con un import o un export al livello più alto è un modulo. Impara gli export con nome e quelli di default, import type ed export type, come l'opzione module sceglie tra output ES module e CommonJS, e perché node16 e nodenext vogliono le estensioni .js negli import.
- NamespaceUn namespace di TypeScript raggruppa valori e tipi sotto un solo nome e viene compilato in un oggetto semplice. Impara la sintassi, come i namespace si fondono tra loro e con funzioni e classi, perché gli ES module li hanno sostituiti e dove li incontri ancora: file di dichiarazione e global augmentation.
- File di dichiarazioneUn file .d.ts descrive i tipi di codice JavaScript senza contenerne nemmeno una riga, e la parola chiave declare fa lo stesso dentro un file .ts. Scopri come vengono generati i file di dichiarazione, a cosa servono i pacchetti @types, come tipizzare un modulo senza tipi e come declare global e la module augmentation estendono i tipi esistenti.
- Strict modestrict: true in tsconfig.json attiva una famiglia di controlli sui tipi: noImplicitAny, strictNullChecks, strictPropertyInitialization e altri cinque. Scopri cosa intercetta ciascuno, come attivare lo strict mode in un progetto esistente e le opzioni utili che strict non include.
- JSONJSON.parse restituisce any, quindi TypeScript si fida di qualunque tipo tu dia al risultato. Scopri come tipizzare il JSON letto, validarlo con un type guard, trasformare un esempio di JSON in un'interfaccia, importare file .json, e cosa fa JSON.stringify a Date, Set e undefined.
Per andare oltre
- Best practiceOtto abitudini TypeScript che evitano bug reali: tieni strict attivo, usa unknown invece di any, lascia lavorare l'inferenza, preferisci le union agli enum, controlla la configurazione con satisfies, modella lo stato con le discriminated union, evita ! e as, e rendi i dati readonly. Ognuna ha un prima e dopo eseguibile.
- Domande da colloquio25 domande da colloquio su TypeScript con risposte brevi, corrette e con codice, raggruppate da principiante ad avanzato: any vs unknown, interface vs type, generics, narrowing, utility types, mapped e conditional types, tipizzazione strutturale, tsconfig e TypeScript 7.