ProgrammationDéveloppeur Frontend

Comment fonctionne le mécanisme Partial dans TypeScript, à quoi sert-il, comment l'appliquer lors de la conception d'API et quelles erreurs typiques sont rencontrées ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Le mécanisme Partial<T> a été introduit dans TypeScript pour faciliter le travail avec des objets dont les propriétés peuvent être temporairement indéfinies. Historiquement, les développeurs devaient créer de nouveaux types manuellement, où toutes les propriétés devenaient optionnelles, ce qui entraînait des duplications de code et des erreurs.

Historique de la question

À l'origine, pour mettre à jour ou créer des objets avec des champs optionnels, il fallait spécifier explicitement chaque propriété optionnelle, ce qui était peu pratique et ne soutenait pas les changements de l'interface d'origine. Ainsi, le type utilitaire Partial<T> est apparu, qui transforme automatiquement toutes les propriétés du type T en optionnelles.

Problème

Lors de la conception d'API, il est souvent nécessaire de mettre à jour uniquement une partie de l'objet, sans toucher aux autres champs. Cela est particulièrement pertinent pour les requêtes PATCH, les formulaires de mise à jour et les fonctions traitant uniquement une partie des données. Sans Partial, la typisation devient complexe et fragile.

Solution

On utilise le type utilitaire Partial<T>, qui est défini comme suit :

// Simplifié : type Partial<T> = { [P in keyof T]?: T[P] };

Ainsi, toutes les propriétés sont rendues optionnelles. Exemple :

interface User { id: number; name: string; email: string; } function updateUser(id: number, user: Partial<User>) { // ... } // Il est possible de transmettre uniquement ce qui est modifié updateUser(1, { email: "test@example.com" });

Caractéristiques clés :

  • Permet de décrire uniquement les champs à mettre à jour ou à définir.
  • Hérite totalement de la structure de l'interface d'origine, garantissant la sécurité des types.
  • S'intègre facilement avec d'autres types utilitaires, comme Pick, Omit.

Questions pièges.

Peut-on utiliser Partial pour rendre tous les champs obligatoires de l'interface d'origine ?

Non, Partial rend toutes les propriétés optionnelles. Pour l'inverse, il existe le type Required<T>.

Que se passe-t-il si l'on utilise Partial avec des propriétés déjà optionnelles ?

Partial ne modifiera simplement pas les propriétés déjà optionnelles, tous les champs resteront optionnels, même s'ils l'étaient avant l'application de Partial.

Exemple :

interface X { x?: number; y: string; } const a: Partial<X> = {}; // les deux propriétés sont désormais optionnelles

Peut-on utiliser Partial pour des structures imbriquées, si l'on veut rendre optionnels uniquement les champs imbriqués ?

Partial ne s'applique pas de manière récursive aux objets imbriqués. Si l'on souhaite rendre toutes les propriétés imbriquées optionnelles, il faudra créer son propre type générique ou utiliser des utilitaires externes.

Erreurs typiques et anti-patterns

  • Essayer d'utiliser Partial pour des structures profondes sans enveloppe récursive, ce qui entraîne des types inattendus.
  • Utiliser Partial pour créer des objets "de zéro" — en conséquence, des objets sans champs obligatoires sont créés.
  • Écraser l'objet entier au lieu de mettre à jour des propriétés individuelles, violant le contrat de type.

Exemple de la vie réelle

Cas négatif

Dans un système CRUD, updateUser accepte Partial<User> et permet de transmettre un objet vide, ce qui entraîne des erreurs à l'exécution : les champs obligatoires sont effacés.

Avantages :

  • Flexibilité de mise à jour ; aucune nécessité de tout transmettre.

Inconvénients :

  • Risque d'erreur — un objet sans champs obligatoires sera enregistré dans la base.

Cas positif

Partial<User> est utilisé uniquement pour décrire le formulaire d'entrée de mise à jour. À la dernière étape, tous les champs sont validés et fusionnés avec l'objet original avant d'être transmis à la base.

Avantages :

  • Typage doux au moment de l'entrée ; les données sont toujours correctes pour la sauvegarde.

Inconvénients :

  • Nécessite une validation supplémentaire et la fusion des données.