ProgrammazioneSenior TypeScript Developer

Che cosa sono i Mapped Types in TypeScript e come usarli per creare tipi generici flessibili? Analizzate in dettaglio le sfumature del loro utilizzo e le potenziali insidie.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

I Mapped Types sono tipi che vengono costruiti dinamicamente tramite la trasformazione (rinominazione, modifica) di tutte le proprietà di un altro tipo. La sintassi si basa sulla costruzione in:

type Readonly<T> = { readonly [K in keyof T]: T[K]; } type User = { name: string; age: number; } const u: Readonly<User> = { name: 'Eve', age: 22 }; u.name = 'Bob'; // Errore: name è solo in lettura

Sfumature:

  • È possibile modificare i modificatori (readonly, optional), rimuoverli o aggiungerli tramite le parole chiave -? o +?.
  • Possono essere applicati in modo annidato, combinati con tipi condizionali, utility types e generics.
  • Gli errori non sono sempre facilmente tracciabili durante lo sviluppo, soprattutto con modifiche complesse e annidate delle gerarchie di tipi.

Esempio con tutti i modificatori:

type PartialMutable<T> = { -readonly [K in keyof T]?: T[K]; };

Domanda insidiosa.

«Applicando un mapped type con il modificatore optional, influisce solo sulle proprietà di primo livello o anche sugli oggetti annidati?»

Risposta: No, il mapped type con optional ? influisce SOLO sulle proprietà di primo livello. Gli oggetti annidati devono essere trasformati separatamente, spesso usando ricorsione o mapped types aggiuntivi.

Esempio:

type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]; };

Esempi di errori reali dovuti alla mancata conoscenza delle sfumature del tema.


Storia

In un progetto, per risparmiare tempo si è utilizzato il comune Partial<T> per la profondità di un modulo. Tuttavia, i campi di secondo e terzo livello non sono diventati opzionali, portando a errori imprevisti a runtime in assenza di chiavi annidate.


Storia

Si è tentato di rimuovere le proprietà readonly solo negli oggetti figli, applicando un mapped type solo al livello superiore:

type Mutable<T> = { -readonly [K in keyof T]: T[K] }

Di conseguenza, i campi di tipo { readonly foo: { readonly bar: number } } sono rimasti invariati nell'annidamento, confondendo il team e complicando la manutenzione.


Storia

In un modello di dati complesso sono stati applicati mapped types annidati per l'intersezione di vari utility types (ad esempio, Readonly & Partial). A causa di un ordine errato nella loro composizione, sono emersi conflitti imprevisti di compatibilità dei tipi, e il compilatore ha iniziato a generare messaggi di errore confusi.