ProgrammatieSenior TypeScript ontwikkelaar

Wat zijn Mapped Types in TypeScript en hoe kun je ze gebruiken om flexibele generieke types te creëren? Bespreek de nuances van hun gebruik en mogelijke valkuilen.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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:

  • Je kunt modificatoren (readonly, optional) aanpassen, verwijderen of toevoegen via het sleutelwoord -? of +?.
  • Ze kunnen genest worden toegepast, gecombineerd met conditional types, utility types en generics.
  • Het is niet altijd gemakkelijk om fouten op het ontwikkelstadium op te sporen, vooral bij complexe geneste modificatie van typehiërarchieën.

Voorbeeld met alle modificatoren:

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

Vraag met een valstrik.

"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]; };

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp.


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.