Mapped Types zijn types die dynamisch worden opgebouwd door alle eigenschappen van een ander type te transformeren (hernoemen, aanpassen). De syntaxis is gebaseerd op de in constructie:
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'; // Fout: name is alleen-lezen
Nuances:
-? of +?.Voorbeeld met alle modificatoren:
type PartialMutable<T> = { -readonly [K in keyof T]?: T[K]; };
"Als je een mapped type met de optional-modificator toepast, heeft dit dan invloed op alleen de eerste-niveau eigenschappen of ook op geneste objecten?"
Antwoord: Nee, mapped type met optional ? heeft alleen invloed op de eerste-niveau eigenschappen. Geneste objecten moeten afzonderlijk worden omgevormd, vaak met behulp van recursie of extra mapped types.
Voorbeeld:
type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]; };
Verhaal
In een project werd, om tijd te besparen, de standaard Partial<T> toegepast voor een diep object van een formulier. Echter, de velden van het tweede en derde niveau werden niet optioneel, wat leidde tot onverwachte fouten tijdens runtime bij het ontbreken van geneste sleutels.
Verhaal
Er was een poging om readonly eigenschappen alleen in geneste objecten te verwijderen door het mapped type alleen op het bovenste niveau toe te passen:
type Mutable<T> = { -readonly [K in keyof T]: T[K] }
Als gevolg hiervan bleven de velden van het type { readonly foo: { readonly bar: number } } onveranderd op de geneste niveaus, wat het team in de war bracht en het onderhoud bemoeilijkte.
Verhaal
In een complex datamodel werden geneste mapped types toegepast voor de intersectie van verschillende utility types (zoals Readonly & Partial). Door de verkeerde volgorde van samenstelling ontstonden onverwachte type-compatibiliteitsconflicten en begon de compiler verwarrende foutmeldingen weer te geven.