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:
-? o +?.Esempio con tutti i modificatori:
type PartialMutable<T> = { -readonly [K in keyof T]?: T[K]; };
«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]; };
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.