React LogoArchitecture front-end
Architecture/Typescript

Les Mapped Types (Types Mappés)

Parfois, vous avez besoin de créer un type de manière dynamique en vous basant sur une union de chaînes de caractères. C'est là qu'interviennent les Mapped Types.

Voyez ça comme la fonction .map() des tableaux JavaScript, mais pour le système de types ! La syntaxe utilise les crochets [K in Union].

Imaginons que vous ayez une union représentant les rôles possibles dans votre application :

type  = 'admin' | 'editor' | 'viewer';

// On boucle sur chaque élément "K" du type Role
type  = {
  [ in ]: boolean;
};

const :  = {
  : true,
  : false,
  : true
};

TypeScript comprend automatiquement que RoleFlags équivaut à un objet contenant { admin: boolean; editor: boolean; viewer: boolean; }.

Key Remapping (Renommer les clés générées)

On peut aller encore plus loin. Depuis TypeScript 4.1, on peut modifier le nom de la clé générée à la volée grâce au mot-clé as et aux Template Literal Types (l'équivalent des backticks en JS).

C'est assez puissant pour générer des types complexes sans se répéter, notamment en combinant avec l'utilitaire Capitalize<T> qui met la première lettre en majuscule :

type  = 'admin' | 'editor' | 'viewer';

// On renomme dynamiquement la clé en ajoutant "is" et une majuscule
type  = {
  [ in  as `is${<>}`]: () => boolean;
};

const :  = {
  : () => true,
  : () => false,
  : () => true,
};

Ce concept est assez présent dans le code source des librairies avancées comme Redux, Zustand ou React Query pour typer automatiquement des objets générés dynamiquement.