TypeScript si è evoluto da un superset di JavaScript di nicchia a un linguaggio centrale per lo sviluppo web moderno.
Nella mia esperienza con le applicazioni web, ho visto in prima persona come il strong typing e la manutenibilità possano ridurre significativamente i bug e migliorare la collaborazione tra i team.
TypeScript offre tutto questo, ed è per questo che è diventato uno standard del settore per lo sviluppo moderno.
Da Microsoft (il suo creatore) a Google, Airbnb e Netflix, molte organizzazioni si affidano a TypeScript per alimentare prodotti scritti con framework come React, Angular e Node.js.
Nel mio lavoro ho spesso visto annunci in cui la padronanza di TypeScript è indicata come requisito fondamentale, non come competenza opzionale.
Avendo usato TypeScript in prima persona, posso dire con certezza che capire i suoi tipi, le interfacce e le funzionalità avanzate è essenziale per qualsiasi sviluppatore che si prepara a colloqui tecnici.
Domande base su TypeScript
Vediamo ora alcune comuni domande di colloquio su TypeScript e come si collegano alla sicurezza e alla chiarezza del codice.
1. Perché usare TypeScript al posto di JavaScript?
TypeScript aggiunge tipizzazione statica e controlli di errore in fase di compilazione, aiutando gli sviluppatori a rilevare presto i bug e a rendere le codebase più prevedibili.
Questo garantisce migliore manutenibilità e scalabilità.
2. Quali problemi risolve TypeScript?
TypeScript affronta i punti deboli di JavaScript in termini di sicurezza dei tipi, scalabilità e leggibilità.
L'imposizione di definizioni di tipo chiare previene bug sottili in runtime e rende i refactor più sicuri.
3. Quali sono i principali vantaggi della tipizzazione statica in TypeScript?
La tipizzazione statica migliora l’affidabilità del codice, l’auto-completamento e la produttività degli sviluppatori.
Aiuta a individuare precocemente gli errori di tipo e consente agli IDE di offrire strumenti più ricchi.
4. Cosa sono le annotazioni di tipo e perché sono utili?
Le annotazioni di tipo permettono agli sviluppatori di dichiarare esplicitamente i tipi delle variabili.
Questo migliora la leggibilità del codice e riduce gli errori in runtime.
Ecco un esempio:
let username:string="DataCamper";let age:number=25;let isAdmin:boolean=true;Offerto da
Nel codice sopra, il compilatore garantisce che a ogni variabile possa essere assegnato solo il tipo corretto.
Ad esempio, se provi ad assegnare una stringa ad age, TypeScript genererà un errore, aiutando a intercettare gli errori in anticipo.
La tipizzazione esplicita è particolarmente importante per i parametri di funzione, i tipi di ritorno e i contratti API, perché comunica le aspettative agli altri sviluppatori.
5. Che cos’è l’inferenza dei tipi in TypeScript?
TypeScript può inferire automaticamente i tipi in base ai valori assegnati.
Questo significa che non devi sempre dichiarare esplicitamente un tipo: TypeScript lo deduce per te.
Ecco un esempio:
let count =10;// inferred as number
count ="hello";// Error: Type 'string' is not assignable to type 'number'Offerto da
In questo esempio, TypeScript deduce che count debba essere un numero in base al valore iniziale, quindi assegnare in seguito una stringa provoca un errore in compilazione.
Le best practice per l’inferenza dei tipi includono:
Usa tipi espliciti per funzioni, classi e interfacce esportate per fornire contratti chiari.
Consenti l’inferenza per le variabili locali quando il tipo è ovvio.
Evita di usare any se non strettamente necessario, perché aggira le funzionalità di sicurezza di TypeScript.
6. Come gestisce TypeScript array, tuple ed enum?
TypeScript consente di applicare tipi rigorosi ad array, tuple ed enum per migliorare la chiarezza e prevenire errori in runtime.
Ecco un esempio di array tipizzato:
let scores:number[]=[95,80,85];
scores.push(100);// OK
scores.push("A+");// ErrorOfferto da
Gli array tipizzati garantiscono che tutti gli elementi dell’array seguano lo stesso tipo.
Le tuple definiscono array a lunghezza fissa con tipi specifici per ogni posizione.
Sono utili per dati strutturati in cui contano l’ordine e il tipo degli elementi.
Ecco un esempio di enum:
enum Status {
Active,
Inactive,
Pending,}let currentStatus: Status = Status.Active;Offerto da
Gli enum forniscono costanti denominate, migliorando la leggibilità e riducendo i valori non validi.
Sono particolarmente utili per codici di stato, ruoli e opzioni di configurazione.
7. Qual è la differenza tra i tipi any, unknown e never?
La tabella seguente evidenzia le principali differenze tra i tipi any, unknown e never in TypeScript.
Tipo
Descrizione
any
Disattiva completamente il controllo dei tipi, consentendo qualsiasi valore.
unknown
Alternativa più sicura ad any: devi controllare il tipo prima di usarlo.
never
Rappresenta valori che non si verificano mai (ad es. funzioni che lanciano sempre un errore).
Ecco un esempio:
functionfail():never{thrownewError("Something went wrong");}Offerto da
Un consiglio è preferire unknown ad any per mantenere la sicurezza dei tipi conservando flessibilità.
8. Qual è la differenza tra null e undefined in TypeScript?
Le differenze chiave tra null e undefined sono:
undefined significa che una variabile è stata dichiarata ma non ha un valore assegnato.
null è un valore esplicito che indica assenza di valore.
La modalità strictNullChecks di TypeScript li tratta come tipi separati, prevenendo bug accidentali legati ai null.
Ecco un esempio:
let a:string|null=null;let b:string|undefined=undefined;Offerto da
9. Cosa fa l’opzione di compilazione strict?
Il flag strict abilita tutte le regole di controllo dei tipi più rigorose di TypeScript, come:
strictNullChecks: Impedisce che i valori null e undefined vengano assegnati alle variabili a meno che non sia esplicitamente consentito, aiutando a evitare errori di riferimento null in runtime.
noImplicitAny: Richiede che tutte le variabili abbiano tipi espliciti o inferiti, impedendo a TypeScript di usare di default any.
strictFunctionTypes: Applica regole più rigorose per la compatibilità dei tipi di funzione, rilevando discrepanze nei parametri e nei tipi di ritorno.
strictBindCallApply: Garantisce che i metodi bind, call e apply siano usati con i tipi di argomento corretti per le funzioni.
Garantisce codice più sicuro e prevedibile e intercetta presto i bug più sottili.
Domande sul sistema di tipi di TypeScript
Vediamo ora alcuni concetti chiave del sistema di tipi di TypeScript spesso discussi nei colloqui tecnici.
10. Qual è la differenza tra interfacce e alias di tipo in TypeScript?
Sia le interfacce che gli alias di tipo descrivono la forma degli oggetti, ma servono a scopi leggermente diversi.
Le interfacce possono essere estese con extends, il che le rende ideali per modelli a oggetti gerarchici.
Gli alias di tipo possono rappresentare unioni, intersezioni, primitivi e tipi composti più complessi.
Ecco un esempio:
interfacePerson{
name:string;
age:number;}typeEmployee={
name:string;
department:string;};Offerto da
Usa le interfacce quando definisci la forma degli oggetti o i contratti delle classi.
Usa gli alias di tipo quando ti servono tipi flessibili e componibili come unioni o intersezioni.
11. Cosa sono i tipi unione e intersezione in TypeScript?
I tipi unione consentono a una variabile di contenere più tipi possibili, mentre i tipi intersezione combinano più tipi in uno solo.
Ecco un esempio di unione:
let id:string|number;
id = ‘abc’;// OK
id =123;// OKOfferto da
Ecco un esempio di intersezione:
typeAdmin={ name:string};typePermissions={ canEdit:boolean};typeAdminUser= Admin & Permissions;Offerto da
I tipi unione sono spesso usati nei parametri di funzione.
I tipi intersezione sono comuni nelle composizioni di oggetti complessi.
12. Che cos’è il narrowing dei tipi e come funzionano i type guard?
Il narrowing dei tipi consente a TypeScript di dedurre un tipo più specifico in base al flusso di controllo.
Ecco un esempio:
functionprintId(id:string|number){if(typeof id ==="string"){console.log(id.toUpperCase());}else{console.log(id.toFixed());}}Offerto da
I type guard garantiscono operazioni sicure in runtime verificando il tipo prima di eseguire azioni specifiche.
Puoi usare:
typeof: per i primitivi
instanceof: per le classi
Custom type guards: usando la sintassi param is Type
I type guard migliorano la sicurezza dei tipi e riducono gli errori in runtime.
13. Cosa sono i tipi letterali e le unioni discriminate in TypeScript?
I tipi letterali limitano una variabile a un insieme specifico di valori predefiniti.
Ecco un esempio:
let direction:"up"|"down"|"left"|"right";Offerto da
Le unioni discriminate combinano tipi letterali con varianti di oggetti per il pattern matching.
Le unioni discriminate consentono diramazioni sicure sui tipi di oggetto e semplificano la logica in applicazioni complesse.
14. Cosa sono keyof, typeof e in in TypeScript?
Questi operatori forniscono una potente riflessione a livello di tipo.
Keyof: ottiene i nomi delle proprietà di un tipo
typeof: ottiene il tipo di un valore
in: usato nei tipi mappati
Ecco un esempio:
typeKeys=keyof User;// "name" | "age"const person ={ name:"Alice", age:25};typePersonType=typeof person;// { name: string; age: number }Offerto da
15. Cosa sono le index signature in TypeScript?
Le index signature consentono oggetti con chiavi dinamiche.
Ecco un esempio:
interfaceErrors{[key:string]:string;}const messages: Errors ={
email:"Invalid email",
password:"Required"};Offerto da
Sono usate per dizionari, oggetti tipo mappa o pattern di configurazione dinamica.
16. Che cos’è la tipizzazione strutturale in TypeScript?
La tipizzazione strutturale (duck typing) significa che i tipi sono compatibili in base alla loro struttura, non al loro nome.
Ecco un esempio:
interfacePoint{ x:number; y:number;}let p ={ x:10, y:20, z:30};let q: Point = p;// OK because structural matchOfferto da
Questo rende TypeScript flessibile e ben integrato con i pattern di JavaScript.
17. Che cos’è il merging delle dichiarazioni in TypeScript?
Il merging delle dichiarazioni si verifica quando TypeScript combina più dichiarazioni con lo stesso nome.
Ecco un esempio di merge di due interfacce:
interfaceUser{ name:string;}interfaceUser{ age:number;}const u: User ={ name:"Rob", age:30};// mergedOfferto da
È utile quando estendi tipi di terze parti o aumenti librerie.
Domande avanzate su TypeScript
Ecco domande e risposte avanzate su TypeScript.
18. Cosa sono i generics in TypeScript e perché sono utili?
I generics ti permettono di scrivere funzioni e classi riutilizzabili e type-safe che funzionano con più tipi di dati.
Ecco un esempio di funzione generica:
functionidentity<T>(value:T):T{return value;}let output =identity<string>("DataCamp");let outputNumber =identity<number>(42);Offerto da
Ecco un esempio di classe generica:
classBox<T>{
content:T;constructor(content:T){this.content = content;}getContent():T{returnthis.content;}}let stringBox =newBox("Hello");let numberBox =newBox(123);Offerto da
Le best practice includono:
Usa nomi descrittivi come <T>, <K, V> o nomi specifici del dominio.
Evita complessità non necessarie.
Usa i vincoli (extends) per limitare i tipi accettabili.
I generics migliorano il riuso del codice riducendo la duplicazione e imponendo tipizzazione coerente.
19. Cosa sono i tipi utility di TypeScript e come si usano?
TypeScript fornisce tipi utility integrati per manipolare e trasformare in modo efficiente i tipi esistenti.
Ecco un esempio:
interfaceTodo{
title:string;
description:string;
completed:boolean;}typePartialTodo= Partial<Todo>;// all properties optionaltypeRequiredTodo= Required<Todo>;// all properties requiredtypeTodoPreview= Pick<Todo,"title"|"completed">;// select specific propertiestypeTodoWithoutDescription= Omit<Todo,"description">;// exclude propertiesOfferto da
Sono particolarmente utili quando lavori con risposte API, form o prop dei componenti.
Un consiglio è sfruttare i tipi utility quando possibile per semplificare il codice e imporre coerenza di tipi.
20. Cosa sono i tipi condizionali e mappati in TypeScript?
I tipi condizionali consentono di definire logica all’interno dei tipi in base alle relazioni tra essi.
Ecco un esempio:
typeIsString<T>=Textendsstring?"yes":"no";typeResult1= IsString<string>;// "yes"typeResult2= IsString<number>;// "no"Offerto da
I tipi mappati permettono di trasformare in una volta sola tutte le proprietà di un tipo.
Ecco un esempio:
typeReadonlyTodo={readonly[Kinkeyof Todo]: Todo[K];};typeOptionalTodo={[Kinkeyof Todo]?: Todo[K];};Offerto da
Le differenze principali sono:
keyof estrae i nomi delle proprietà di un tipo.
typeof ottiene il tipo di una variabile o di un oggetto. Combinarli consente manipolazioni dinamiche dei tipi e refactor più sicuri.
21. A cosa serve la parola chiave infer in TypeScript?
infer ti consente di estrarre (inferire) un tipo all’interno di un tipo condizionale.
Ecco un esempio:
typeReturnType<T>=Textends(...args:any[])=>inferR?R:never;typeR= ReturnType<()=>number>;// numberOfferto da
Spesso usata in utility avanzate e trasformazioni di tipi generici.
22. Cosa sono i template literal types?
I template literal types costruiscono tipi stringa usando l’interpolazione.
Ecco un esempio:
typeEvent= ${string}Changed;let e: Event ="nameChanged";// OKOfferto da
Sono utili per:
Denominazione di eventi
Pattern di classi CSS
Pattern di route API
23. Cosa sono satisfies e as const in TypeScript?
satisfies garantisce che un valore soddisfi un tipo ma ne preserva il tipo letterale.
Per esempio:
const config ={
mode:"dark",
version:1} satisfies { mode:string; version:number};Offerto da
as const rende tutte le proprietà di sola lettura e letterali.
Per esempio:
const directions =["up","down"]asconst;// type is readonly ["up", "down"]Offerto da
Sia satisfies che as const sono utili in React, negli oggetti di configurazione e nelle unioni discriminate.
Domande su funzioni e oggetti in TypeScript
In questa sezione esploreremo domande di colloquio su TypeScript relative a funzioni e oggetti.
24. Come funziona l’overloading delle funzioni in TypeScript?
L’overloading delle funzioni ti consente di definire più firme per una funzione in base a tipi o pattern diversi di argomenti.
Ecco un esempio:
functionadd(a:number, b:number):number;functionadd(a:string, b:string):string;functionadd(a:any, b:any):any{return a + b;}let sumNumbers =add(5,10);// 15let sumStrings =add("Hello, ","World");// "Hello, World"Offerto da
Le best practice includono:
Dichiara tutti gli overload possibili prima dell’implementazione.
Usa i type guard per gestire in sicurezza più tipi.
25. Cosa sono i parametri opzionali e rest in TypeScript?
I parametri opzionali e rest rendono le funzioni più flessibili ed espressive.
Ecco un esempio:
functiongreet(name:string, age?:number){console.log(Hello ${name}, age: ${age ??"unknown"});}functionsum(...numbers:number[]){return numbers.reduce((a, b)=> a + b,0);}Offerto da
Le regole chiave per l’uso di parametri opzionali e rest sono:
Usa ? per i parametri opzionali.
Usa ... per i parametri rest (argomenti variadici).
Questi aspetti vengono spesso testati nei colloqui per valutare come gestisci input dinamici delle funzioni.
26. Qual è la differenza tra readonly e const in TypeScript?
const si applica alle variabili, mentre readonly si applica alle proprietà degli oggetti.
Ecco un esempio:
interfaceUser{readonly id:number;
name:string;}const user: User ={ id:1, name:"Bob"};// user.id = 2; // Error: Cannot assign to 'id'const{ id, name }= user;console.log(User ${name} has ID ${id});Offerto da
Alcune best practice per usare readonly e const sono:
Usa readonly per oggetti che non dovrebbero cambiare, come dati restituiti da un’API.
Usa const per variabili che non devono essere riassegnate.
Combina destructuring con annotazioni di tipo per un codice più pulito e auto-documentante.
27. Che cos’è la varianza dei tipi di funzione (covarianza e controvarianza)?
La varianza dei tipi di funzione descrive come TypeScript decide se un tipo di funzione può sostituirne in sicurezza un altro, in base ai tipi dei parametri e dei valori di ritorno.
Tipi di ritorno: Covarianza
Una funzione può restituire un tipo più specifico di quello atteso dal chiamante. Ad esempio:
typeAnimal={ name:string};typeDog= Animal &{bark:()=>void};letf:()=> Animal;letg:()=>Dog=()=>({ name:"Rex",bark(){}});
f = g;// OK: Dog is a subtype of AnimalOfferto da
Tipi di parametro: Controvarianza
Una funzione può accettare tipi di parametro più generali di quelli attesi. Ad esempio:
typeDog={ name:string;bark:()=>void};typeAnimal={ name:string};typeHandleDog=(dog: Dog)=>void;typeHandleAnimal=(animal: Animal)=>void;let handleDog:HandleDog= d =>console.log(d.bark());let handleAnimal:HandleAnimal= a =>console.log(a.name);// A function that accepts an Animal is more general,// so it can stand in for one that accepts a Dog
handleDog = handleAnimal;// OKOfferto da
28. Cosa sono i tipi this in TypeScript?
this types consentono ai metodi di restituire lo stesso tipo della classe, utile per API fluenti:
classBuilder{setName(name:string):this{// ...returnthis;}}newBuilder().setName("Test");// chaining worksOfferto da
Domande OOP su TypeScript
Le seguenti domande coprono concetti OOP chiave di TypeScript spesso discussi nei colloqui tecnici.
29. Come supporta TypeScript la programmazione orientata agli oggetti (OOP)?
TypeScript supporta principi OOP come classi, ereditarietà e modificatori di accesso.
Le classi definiscono blueprint riutilizzabili per gli oggetti, e l’ereditarietà consente a una classe di estenderne un’altra per condividere proprietà e comportamenti.
Ecco un esempio:
classAnimal{constructor(public name:string){}move(distance:number){console.log(${this.name} moved ${distance}m.);}}classDogextendsAnimal{bark(){console.log("Woof!");}}const dog =newDog("Buddy");
dog.bark();// Woof!
dog.move(10);// Buddy moved 10m.Offerto da
I modificatori di accesso includono:
public: accessibile ovunque
protected: accessibile nella classe e nelle sue sottoclassi
private: accessibile solo all’interno della classe dichiarante
Un consiglio è usare i modificatori di accesso per garantire l’incapsulamento, che evita modifiche indesiderate della logica o dello stato interni della classe.
30. Qual è la differenza tra classi astratte e interfacce in TypeScript?
Sia le classi astratte che le interfacce definiscono contratti per oggetti o classi, ma hanno scopi diversi.
Le classi astratte possono includere implementazioni condivise e metodi astratti.
Le interfacce descrivono solo la struttura, non l’implementazione.
Ecco un esempio:
abstractclassShape{abstractgetArea():number;// must be implemented}classCircleextendsShape{constructor(public radius:number){super();}getArea():number{return Math.PI*this.radius **2;}}Offerto da
Le best practice includono:
Usa classi astratte quando ti serve logica condivisa tra classi correlate.
Usa interfacce per contratti di tipo flessibili e design disaccoppiato.
31. Qual è la differenza tra i modificatori private, protected e public?
Ecco un confronto dei modificatori di accesso di TypeScript e di ciò che controllano:
Modificatore
Descrizione
public
Accessibile ovunque.
protected
Accessibile all’interno della classe e delle sue sottoclassi.
private
Accessibile solo all’interno della classe dichiarante.
Usare il modificatore di accesso corretto promuove l’incapsulamento, che garantisce che lo stato e la logica interni non possano essere accessi o modificati inaspettatamente.
32. Qual è la differenza tra implements ed extends?
extends eredita comportamento e proprietà, mentre implements impone un contratto ma non fornisce l’implementazione
Ecco un esempio:
interfaceLogger{log(msg:string):void;}classBase{foo(){}}classMyClassextendsBaseimplementsLogger{log(msg:string){}}Offerto da
33. Come funzionano i mixin in TypeScript?
I mixin consentono componenti di classe riutilizzabili multipli.
Ecco un esempio:
typeConstructor<T={}>=new(...args:any[])=>T;functionTimestamped<TBase extends Constructor>(Base: TBase){returnclassextends Base {
timestamp = Date.now();};}classUser{}const TimestampedUser =Timestamped(User);Offerto da
Utile quando ti servono pattern di ereditarietà multipla.
Domande pratiche su TypeScript
Queste domande si concentrano su applicazioni reali di TypeScript che spesso emergono nei colloqui.
34. Come migreresti un progetto JavaScript a TypeScript?
La migrazione di una codebase JavaScript legacy a TypeScript dovrebbe essere incrementale per minimizzare rischi e interruzioni.
L’approccio consigliato è:
Rinomina i file .js in .ts.
Abilita allowJs e checkJs in tsconfig.json.
Aggiungi gradualmente i tipi, partendo da funzioni o moduli core.
Usa any temporaneamente, poi sostituiscilo con tipi adeguati man mano che affini la codebase.
Esempio di tsconfig.json per migrazione graduale:
{"compilerOptions":{"allowJs":true,"checkJs":true,"strict":true}}Offerto da
La migrazione graduale garantisce stabilità e consente ai team di beneficiare presto del type checking senza grandi riscritture.
35. Come si usa TypeScript con React?
Usare TypeScript in React migliora la sicurezza dei tipi per prop e stato, aiutando a prevenire errori in runtime.
Ecco un esempio:
interfaceProps{
title:string;}const Header: React.FC<Props>=({ title })=><h1>{title}</h1>;Offerto da
Definire i tipi delle prop aiuta TypeScript a intercettare prop mancanti o di tipo errato in compilazione, migliorando affidabilità e produttività.
36. Come si usa TypeScript con Node.js?
TypeScript migliora le applicazioni Node.js aggiungendo sicurezza dei tipi per route API, configurazioni e middleware.
Tipizzare Request e Response garantisce l’uso corretto dei parametri e previene comuni errori in runtime.
TypeScript rende le API Node.js più facili da mantenere e da rifattorizzare in sicurezza.
37. Come gestisci librerie JavaScript di terze parti prive di definizioni TypeScript?
Alcune librerie non includono tipi integrati. In questi casi, hai due opzioni principali:
Opzione 1: installare tipi mantenuti dalla community
npm install --save-dev @types/library-nameOfferto da
Opzione 2: creare un file di dichiarazione personalizzato
// custom.d.tsdeclaremodule"legacy-library"{exportfunctioninit():void;}Offerto da
I consigli includono:
Controlla sempre @types prima di scrivere dichiarazioni personalizzate.
Aggiungi gradualmente i tipi per librerie complesse per garantire compatibilità.
Una corretta tipizzazione delle librerie di terze parti aumenta la fiducia e riduce i bug in runtime.
Domande su configurazione e strumenti di TypeScript
Questa sezione tratta argomenti essenziali di configurazione e tooling di TypeScript spesso discussi nei colloqui tecnici.
38. Che cos’è tsconfig.json e perché è importante?
Il file tsconfig.json è la configurazione centrale di qualsiasi progetto TypeScript.
Definisce il comportamento del compilatore, include i file e abilita funzionalità.
Ecco un esempio:
{"compilerOptions":{"target":"ES2020","module":"commonjs","strict":true,"outDir":"./dist","esModuleInterop":true,"forceConsistentCasingInFileNames":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true},"include":["src"],"exclude":["node_modules","dist"]}Offerto da
Le impostazioni chiave includono:
target: versione di JavaScript per l’output
module: sistema di moduli (CommonJS, ESNext, ecc.)
strict: abilita tutte le opzioni di controllo rigoroso dei tipi
outDir: cartella di output per il codice compilato
esModuleInterop: consente import di moduli CommonJS
Assicurati di abilitare la modalità strict per intercettare presto potenziali bug e migliorare la manutenibilità.
39. Come configuri TypeScript con strumenti di build come Webpack, Vite o Babel?
TypeScript si integra perfettamente con i moderni sistemi di build.
Le configurazioni più comuni includono:
Webpack: ts-loader per la compilazione al volo
Vite: vite-plugin-ts per build veloci
Babel: @babel/preset-typescript per ambienti fortemente orientati a JS
Allinea le impostazioni di compilatore e bundler, abilita build incrementali e usa le source map per un debug più semplice.
40. Come configuri ESLint con TypeScript per una migliore qualità del codice?
ESLint aiuta a mantenere standard di codice coerenti e a intercettare errori in anticipo.
Installa i pacchetti necessari:
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-devOfferto da
Esempio di configurazione ESLint:
{"parser":"@typescript-eslint/parser","plugins":["@typescript-eslint"],"extends":["eslint:recommended","plugin:@typescript-eslint/recommended"],"rules":{"@typescript-eslint/no-explicit-any":"warn","@typescript-eslint/explicit-function-return-type":"off"}}Offerto da
I consigli includono:
Evita di disabilitare le regole globalmente.
Affina le regole per progetto per bilanciare sicurezza dei tipi e flessibilità.
Usa ESLint con Prettier per una codebase coerente e pulita.
Consigli per superare il tuo colloquio su TypeScript
Prima del colloquio, dovresti concentrarti nel padroneggiare sia le competenze tecniche sia quelle comunicative.
Ecco alcuni modi per farlo:
Approccio allo studio:
Rivedi la documentazione ufficiale su tipi avanzati, generics e tipi utility.
Concentrati su casi d’uso reali piuttosto che sulla memorizzazione.
Esercitati a leggere e comprendere gli errori di tipo, dato che i messaggi del compilatore TypeScript sono spesso parte delle prove tecniche.
Progetti pratici:
Costruisci app piccole ma complete per dimostrare competenze pratiche:
To-Do List in React con prop e stato tipizzati.
API REST in Express con oggetti request e response tipizzati.
Librerie di utility usando generics e tipi mappati.
Errori comuni:
Abusare di any, che mina la sicurezza dei tipi di TypeScript.
Ignorare gli avvisi del compilatore, non abilitare la modalità strict, che porta a bug in runtime.
Confondere null e undefined nelle definizioni di tipo.
Dimenticare di installare o configurare le definizioni di tipo per librerie di terze parti.
Consigli di comunicazione:
Durante i colloqui, spiega chiaramente il tuo ragionamento dietro le decisioni sui tipi.
Descrivi i trade-off tra gli approcci (per esempio: interfaccia vs alias di tipo o classe astratta vs interfaccia).
Mostra come TypeScript migliori manutenibilità e scalabilità nei progetti.
Conclusione
TypeScript continua a dominare lo sviluppo web moderno perché impone tipi di dati chiari e coerenti che aiutano a prevenire bug e a migliorare la scalabilità nei progetti di grandi dimensioni.
Sono Don—Consulente, Developer, Ingegnere, Architetto Digitale e Scrittore (in pratica, indosso molti cappelli 👨💻🎩). Mi piace mantenere le piattaforme digitali stabili e trovare sempre nuovi modi per migliorarle. Quando non scrivo codice, scrivo di intelligenza artificiale, data science e tecnologia in generale.
Nel corso degli anni ho lavorato su tutto: dalla creazione e ottimizzazione di software al deployment di modelli di IA, fino alla progettazione di soluzioni cloud. Ho conseguito un Master of Science in Artificial Intelligence e un Bachelor of Science in Computer Science, entrambi alla Brunel University London.
FAQ
A cosa serve TypeScript?⌄
TypeScript è un superset tipizzato di JavaScript che compila in JavaScript puro. Si usa per creare applicazioni scalabili e manutenibili con controllo statico dei tipi.
Perché TypeScript è importante per gli sviluppatori nel 2026?⌄
Man mano che framework come React, Angular e Node.js standardizzano su TypeScript, è ormai una competenza chiave testata nella maggior parte dei colloqui front-end e full-stack.
Come posso praticare TypeScript prima dei colloqui?⌄
Crea piccoli progetti (come una To-Do app in React o una API in Node.js) per rafforzare la comprensione e prepararti a prove pratiche durante i colloqui.
Quali sono gli errori comuni su TypeScript da evitare ai colloqui?⌄
Abusare di ‘any’, ignorare gli avvisi del compilatore, saltare la modalità strict e non saper spiegare le scelte sui tipi sono alcuni degli errori più comuni.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
TypeScript si è evoluto da un superset di JavaScript di nicchia a un linguaggio centrale per lo sviluppo web moderno.
Nella mia esperienza con le applicazioni web, ho visto in prima persona come il strong typing e la manutenibilità possano ridurre significativamente i bug e migliorare la collaborazione tra i team.
TypeScript offre tutto questo, ed è per questo che è diventato uno standard del settore per lo sviluppo moderno.
Da Microsoft (il suo creatore) a Google, Airbnb e Netflix, molte organizzazioni si affidano a TypeScript per alimentare prodotti scritti con framework come React, Angular e Node.js.
Nel mio lavoro ho spesso visto annunci in cui la padronanza di TypeScript è indicata come requisito fondamentale, non come competenza opzionale.
Avendo usato TypeScript in prima persona, posso dire con certezza che capire i suoi tipi, le interfacce e le funzionalità avanzate è essenziale per qualsiasi sviluppatore che si prepara a colloqui tecnici.
Domande base su TypeScript
Vediamo ora alcune comuni domande di colloquio su TypeScript e come si collegano alla sicurezza e alla chiarezza del codice.
1. Perché usare TypeScript al posto di JavaScript?
TypeScript aggiunge tipizzazione statica e controlli di errore in fase di compilazione, aiutando gli sviluppatori a rilevare presto i bug e a rendere le codebase più prevedibili.
Questo garantisce migliore manutenibilità e scalabilità.
2. Quali problemi risolve TypeScript?
TypeScript affronta i punti deboli di JavaScript in termini di sicurezza dei tipi, scalabilità e leggibilità.
L'imposizione di definizioni di tipo chiare previene bug sottili in runtime e rende i refactor più sicuri.
3. Quali sono i principali vantaggi della tipizzazione statica in TypeScript?
La tipizzazione statica migliora l’affidabilità del codice, l’auto-completamento e la produttività degli sviluppatori.
Aiuta a individuare precocemente gli errori di tipo e consente agli IDE di offrire strumenti più ricchi.
4. Cosa sono le annotazioni di tipo e perché sono utili?
Le annotazioni di tipo permettono agli sviluppatori di dichiarare esplicitamente i tipi delle variabili.
Questo migliora la leggibilità del codice e riduce gli errori in runtime.
Ecco un esempio:
Nel codice sopra, il compilatore garantisce che a ogni variabile possa essere assegnato solo il tipo corretto.
Ad esempio, se provi ad assegnare una stringa ad age, TypeScript genererà un errore, aiutando a intercettare gli errori in anticipo.
La tipizzazione esplicita è particolarmente importante per i parametri di funzione, i tipi di ritorno e i contratti API, perché comunica le aspettative agli altri sviluppatori.
5. Che cos’è l’inferenza dei tipi in TypeScript?
TypeScript può inferire automaticamente i tipi in base ai valori assegnati.
Questo significa che non devi sempre dichiarare esplicitamente un tipo: TypeScript lo deduce per te.
Ecco un esempio:
In questo esempio, TypeScript deduce che count debba essere un numero in base al valore iniziale, quindi assegnare in seguito una stringa provoca un errore in compilazione.
Le best practice per l’inferenza dei tipi includono:
6. Come gestisce TypeScript array, tuple ed enum?
TypeScript consente di applicare tipi rigorosi ad array, tuple ed enum per migliorare la chiarezza e prevenire errori in runtime.
Ecco un esempio di array tipizzato:
Gli array tipizzati garantiscono che tutti gli elementi dell’array seguano lo stesso tipo.
Ecco un esempio di tupla:
Le tuple definiscono array a lunghezza fissa con tipi specifici per ogni posizione.
Sono utili per dati strutturati in cui contano l’ordine e il tipo degli elementi.
Ecco un esempio di enum:
Gli enum forniscono costanti denominate, migliorando la leggibilità e riducendo i valori non validi.
Sono particolarmente utili per codici di stato, ruoli e opzioni di configurazione.
7. Qual è la differenza tra i tipi any, unknown e never?
La tabella seguente evidenzia le principali differenze tra i tipi any, unknown e never in TypeScript.
Tipo
Descrizione
any
Disattiva completamente il controllo dei tipi, consentendo qualsiasi valore.
unknown
Alternativa più sicura ad any: devi controllare il tipo prima di usarlo.
never
Rappresenta valori che non si verificano mai (ad es. funzioni che lanciano sempre un errore).
Ecco un esempio:
Un consiglio è preferire unknown ad any per mantenere la sicurezza dei tipi conservando flessibilità.
8. Qual è la differenza tra null e undefined in TypeScript?
Le differenze chiave tra null e undefined sono:
undefinedsignifica che una variabile è stata dichiarata ma non ha un valore assegnato.nullè un valore esplicito che indica assenza di valore.La modalità strictNullChecks di TypeScript li tratta come tipi separati, prevenendo bug accidentali legati ai null.
Ecco un esempio:
9. Cosa fa l’opzione di compilazione strict?
Il flag
strictabilita tutte le regole di controllo dei tipi più rigorose di TypeScript, come:nulleundefinedvengano assegnati alle variabili a meno che non sia esplicitamente consentito, aiutando a evitare errori di riferimento null in runtime.noImplicitAny: Richiede che tutte le variabili abbiano tipi espliciti o inferiti, impedendo a TypeScript di usare di default
any.strictFunctionTypes: Applica regole più rigorose per la compatibilità dei tipi di funzione, rilevando discrepanze nei parametri e nei tipi di ritorno.
strictBindCallApply: Garantisce che i metodi
bind,calleapplysiano usati con i tipi di argomento corretti per le funzioni.Garantisce codice più sicuro e prevedibile e intercetta presto i bug più sottili.
Domande sul sistema di tipi di TypeScript
Vediamo ora alcuni concetti chiave del sistema di tipi di TypeScript spesso discussi nei colloqui tecnici.
10. Qual è la differenza tra interfacce e alias di tipo in TypeScript?
Sia le interfacce che gli alias di tipo descrivono la forma degli oggetti, ma servono a scopi leggermente diversi.
Le interfacce possono essere estese con extends, il che le rende ideali per modelli a oggetti gerarchici.
Gli alias di tipo possono rappresentare unioni, intersezioni, primitivi e tipi composti più complessi.
Ecco un esempio:
Usa le interfacce quando definisci la forma degli oggetti o i contratti delle classi.
Usa gli alias di tipo quando ti servono tipi flessibili e componibili come unioni o intersezioni.
11. Cosa sono i tipi unione e intersezione in TypeScript?
I tipi unione consentono a una variabile di contenere più tipi possibili, mentre i tipi intersezione combinano più tipi in uno solo.
Ecco un esempio di unione:
Ecco un esempio di intersezione:
I tipi unione sono spesso usati nei parametri di funzione.
I tipi intersezione sono comuni nelle composizioni di oggetti complessi.
12. Che cos’è il narrowing dei tipi e come funzionano i type guard?
Il narrowing dei tipi consente a TypeScript di dedurre un tipo più specifico in base al flusso di controllo.
Ecco un esempio:
I type guard garantiscono operazioni sicure in runtime verificando il tipo prima di eseguire azioni specifiche.
Puoi usare:
typeof: per i primitiviinstanceof: per le classiCustom type guards: usando la sintassi param isTypeI type guard migliorano la sicurezza dei tipi e riducono gli errori in runtime.
13. Cosa sono i tipi letterali e le unioni discriminate in TypeScript?
I tipi letterali limitano una variabile a un insieme specifico di valori predefiniti.
Ecco un esempio:
Le unioni discriminate combinano tipi letterali con varianti di oggetti per il pattern matching.
Ecco un esempio:
Le unioni discriminate consentono diramazioni sicure sui tipi di oggetto e semplificano la logica in applicazioni complesse.
14. Cosa sono keyof, typeof e in in TypeScript?
Questi operatori forniscono una potente riflessione a livello di tipo.
Keyof: ottiene i nomi delle proprietà di un tipotypeof: ottiene il tipo di un valorein: usato nei tipi mappatiEcco un esempio:
15. Cosa sono le index signature in TypeScript?
Le index signature consentono oggetti con chiavi dinamiche.
Ecco un esempio:
Sono usate per dizionari, oggetti tipo mappa o pattern di configurazione dinamica.
16. Che cos’è la tipizzazione strutturale in TypeScript?
La tipizzazione strutturale (duck typing) significa che i tipi sono compatibili in base alla loro struttura, non al loro nome.
Ecco un esempio:
Questo rende TypeScript flessibile e ben integrato con i pattern di JavaScript.
17. Che cos’è il merging delle dichiarazioni in TypeScript?
Il merging delle dichiarazioni si verifica quando TypeScript combina più dichiarazioni con lo stesso nome.
Ecco un esempio di merge di due interfacce:
È utile quando estendi tipi di terze parti o aumenti librerie.
Domande avanzate su TypeScript
Ecco domande e risposte avanzate su TypeScript.
18. Cosa sono i generics in TypeScript e perché sono utili?
I generics ti permettono di scrivere funzioni e classi riutilizzabili e type-safe che funzionano con più tipi di dati.
Ecco un esempio di funzione generica:
Ecco un esempio di classe generica:
Le best practice includono:
Usa nomi descrittivi come
<T>,<K, V>o nomi specifici del dominio.Evita complessità non necessarie.
Usa i vincoli (extends) per limitare i tipi accettabili.
I generics migliorano il riuso del codice riducendo la duplicazione e imponendo tipizzazione coerente.
19. Cosa sono i tipi utility di TypeScript e come si usano?
TypeScript fornisce tipi utility integrati per manipolare e trasformare in modo efficiente i tipi esistenti.
Ecco un esempio:
Sono particolarmente utili quando lavori con risposte API, form o prop dei componenti.
Un consiglio è sfruttare i tipi utility quando possibile per semplificare il codice e imporre coerenza di tipi.
20. Cosa sono i tipi condizionali e mappati in TypeScript?
I tipi condizionali consentono di definire logica all’interno dei tipi in base alle relazioni tra essi.
Ecco un esempio:
I tipi mappati permettono di trasformare in una volta sola tutte le proprietà di un tipo.
Ecco un esempio:
Le differenze principali sono:
21. A cosa serve la parola chiave infer in TypeScript?
inferti consente di estrarre (inferire) un tipo all’interno di un tipo condizionale.Ecco un esempio:
Spesso usata in utility avanzate e trasformazioni di tipi generici.
22. Cosa sono i template literal types?
I template literal types costruiscono tipi stringa usando l’interpolazione.
Ecco un esempio:
Sono utili per:
23. Cosa sono satisfies e as const in TypeScript?
satisfiesgarantisce che un valore soddisfi un tipo ma ne preserva il tipo letterale.Per esempio:
as constrende tutte le proprietà di sola lettura e letterali.Per esempio:
Sia
satisfiescheas constsono utili in React, negli oggetti di configurazione e nelle unioni discriminate.Domande su funzioni e oggetti in TypeScript
In questa sezione esploreremo domande di colloquio su TypeScript relative a funzioni e oggetti.
24. Come funziona l’overloading delle funzioni in TypeScript?
L’overloading delle funzioni ti consente di definire più firme per una funzione in base a tipi o pattern diversi di argomenti.
Ecco un esempio:
Le best practice includono:
25. Cosa sono i parametri opzionali e rest in TypeScript?
I parametri opzionali e rest rendono le funzioni più flessibili ed espressive.
Ecco un esempio:
Le regole chiave per l’uso di parametri opzionali e rest sono:
Usa
?per i parametri opzionali.Usa
...per i parametri rest (argomenti variadici).Questi aspetti vengono spesso testati nei colloqui per valutare come gestisci input dinamici delle funzioni.
26. Qual è la differenza tra readonly e const in TypeScript?
constsi applica alle variabili, mentrereadonlysi applica alle proprietà degli oggetti.Ecco un esempio:
Alcune best practice per usare
readonlyeconstsono:27. Che cos’è la varianza dei tipi di funzione (covarianza e controvarianza)?
La varianza dei tipi di funzione descrive come TypeScript decide se un tipo di funzione può sostituirne in sicurezza un altro, in base ai tipi dei parametri e dei valori di ritorno.
Tipi di ritorno: Covarianza
Una funzione può restituire un tipo più specifico di quello atteso dal chiamante. Ad esempio:
Tipi di parametro: Controvarianza
Una funzione può accettare tipi di parametro più generali di quelli attesi. Ad esempio:
28. Cosa sono i tipi this in TypeScript?
thistypes consentono ai metodi di restituire lo stesso tipo della classe, utile per API fluenti:Domande OOP su TypeScript
Le seguenti domande coprono concetti OOP chiave di TypeScript spesso discussi nei colloqui tecnici.
29. Come supporta TypeScript la programmazione orientata agli oggetti (OOP)?
TypeScript supporta principi OOP come classi, ereditarietà e modificatori di accesso.
Le classi definiscono blueprint riutilizzabili per gli oggetti, e l’ereditarietà consente a una classe di estenderne un’altra per condividere proprietà e comportamenti.
Ecco un esempio:
I modificatori di accesso includono:
Un consiglio è usare i modificatori di accesso per garantire l’incapsulamento, che evita modifiche indesiderate della logica o dello stato interni della classe.
30. Qual è la differenza tra classi astratte e interfacce in TypeScript?
Sia le classi astratte che le interfacce definiscono contratti per oggetti o classi, ma hanno scopi diversi.
Le classi astratte possono includere implementazioni condivise e metodi astratti.
Le interfacce descrivono solo la struttura, non l’implementazione.
Ecco un esempio:
Le best practice includono:
31. Qual è la differenza tra i modificatori private, protected e public?
Ecco un confronto dei modificatori di accesso di TypeScript e di ciò che controllano:
Modificatore
Descrizione
public
Accessibile ovunque.
protected
Accessibile all’interno della classe e delle sue sottoclassi.
private
Accessibile solo all’interno della classe dichiarante.
Usare il modificatore di accesso corretto promuove l’incapsulamento, che garantisce che lo stato e la logica interni non possano essere accessi o modificati inaspettatamente.
32. Qual è la differenza tra implements ed extends?
extendseredita comportamento e proprietà, mentreimplementsimpone un contratto ma non fornisce l’implementazioneEcco un esempio:
33. Come funzionano i mixin in TypeScript?
I mixin consentono componenti di classe riutilizzabili multipli.
Ecco un esempio:
Utile quando ti servono pattern di ereditarietà multipla.
Domande pratiche su TypeScript
Queste domande si concentrano su applicazioni reali di TypeScript che spesso emergono nei colloqui.
34. Come migreresti un progetto JavaScript a TypeScript?
La migrazione di una codebase JavaScript legacy a TypeScript dovrebbe essere incrementale per minimizzare rischi e interruzioni.
L’approccio consigliato è:
Rinomina i file
.jsin.ts.Abilita
allowJsecheckJsin tsconfig.json.Aggiungi gradualmente i tipi, partendo da funzioni o moduli core.
Usa any temporaneamente, poi sostituiscilo con tipi adeguati man mano che affini la codebase.
Esempio di tsconfig.json per migrazione graduale:
La migrazione graduale garantisce stabilità e consente ai team di beneficiare presto del type checking senza grandi riscritture.
35. Come si usa TypeScript con React?
Usare TypeScript in React migliora la sicurezza dei tipi per prop e stato, aiutando a prevenire errori in runtime.
Ecco un esempio:
Definire i tipi delle prop aiuta TypeScript a intercettare prop mancanti o di tipo errato in compilazione, migliorando affidabilità e produttività.
36. Come si usa TypeScript con Node.js?
TypeScript migliora le applicazioni Node.js aggiungendo sicurezza dei tipi per route API, configurazioni e middleware.
Ecco un esempio:
Tipizzare
RequesteResponsegarantisce l’uso corretto dei parametri e previene comuni errori in runtime.TypeScript rende le API Node.js più facili da mantenere e da rifattorizzare in sicurezza.
37. Come gestisci librerie JavaScript di terze parti prive di definizioni TypeScript?
Alcune librerie non includono tipi integrati. In questi casi, hai due opzioni principali:
Opzione 1: installare tipi mantenuti dalla community
Opzione 2: creare un file di dichiarazione personalizzato
I consigli includono:
Controlla sempre
@typesprima di scrivere dichiarazioni personalizzate.Aggiungi gradualmente i tipi per librerie complesse per garantire compatibilità.
Una corretta tipizzazione delle librerie di terze parti aumenta la fiducia e riduce i bug in runtime.
Domande su configurazione e strumenti di TypeScript
Questa sezione tratta argomenti essenziali di configurazione e tooling di TypeScript spesso discussi nei colloqui tecnici.
38. Che cos’è tsconfig.json e perché è importante?
Il file tsconfig.json è la configurazione centrale di qualsiasi progetto TypeScript.
Definisce il comportamento del compilatore, include i file e abilita funzionalità.
Ecco un esempio:
Le impostazioni chiave includono:
target: versione di JavaScript per l’outputmodule: sistema di moduli (CommonJS, ESNext, ecc.)strict: abilita tutte le opzioni di controllo rigoroso dei tipioutDir: cartella di output per il codice compilatoesModuleInterop: consente import di moduli CommonJSAssicurati di abilitare la modalità strict per intercettare presto potenziali bug e migliorare la manutenibilità.
39. Come configuri TypeScript con strumenti di build come Webpack, Vite o Babel?
TypeScript si integra perfettamente con i moderni sistemi di build.
Le configurazioni più comuni includono:
Webpack:
ts-loaderper la compilazione al voloVite:
vite-plugin-tsper build velociBabel:
@babel/preset-typescriptper ambienti fortemente orientati a JSEsempio di configurazione Vite:
Allinea le impostazioni di compilatore e bundler, abilita build incrementali e usa le source map per un debug più semplice.
40. Come configuri ESLint con TypeScript per una migliore qualità del codice?
ESLint aiuta a mantenere standard di codice coerenti e a intercettare errori in anticipo.
Installa i pacchetti necessari:
Esempio di configurazione ESLint:
I consigli includono:
Consigli per superare il tuo colloquio su TypeScript
Prima del colloquio, dovresti concentrarti nel padroneggiare sia le competenze tecniche sia quelle comunicative.
Ecco alcuni modi per farlo:
Approccio allo studio:
Progetti pratici:
Errori comuni:
Consigli di comunicazione:
Conclusione
TypeScript continua a dominare lo sviluppo web moderno perché impone tipi di dati chiari e coerenti che aiutano a prevenire bug e a migliorare la scalabilità nei progetti di grandi dimensioni.
Per continuare a imparare, esplora il nostro catalogo completo di corsi per ampliare le tue conoscenze su diverse tecnologie.