ProgrammationDéveloppeur Fullstack

Comment implémenter et typifier une fonction avec déstructuration de paramètres imbriqués en TypeScript ? Quels sont les points à considérer lors de l'utilisation de valeurs par défaut, de propriétés optionnelles et obligatoires ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question : En JavaScript, les fonctions utilisent souvent la déstructuration d'objets directement dans la signature. En TypeScript, cette approche nécessite une description claire de la structure des paramètres déstructurés et la définition de valeurs par défaut, sinon des erreurs peuvent survenir lors de l'accès à des propriétés inexistantes et une mauvaise inférence de type.

Problème : Il n'est pas évident de décrire correctement le type de tout le paramètre ou des propriétés imbriquées spécifiques dans l'objet déstructuré, surtout en présence de champs optionnels et imbriqués, ainsi que de valeurs par défaut.

Solution : Décrivez toujours un type ou une interface séparée pour la structure des paramètres de fonction, indiquez clairement quelles propriétés sont obligatoires, lesquelles sont optionnelles, et définissez les valeurs par défaut dans le corps de la fonction ou directement dans les paramètres à l'aide de la syntaxe ES6.

Exemple de code :

interface UserOptions { name: string; age?: number; address?: { city: string; zipcode?: string }; } function registerUser( { name, age = 18, address = { city: 'Inconnu' } }: UserOptions ): string { return `${name}, ${age}, ${address.city}`; }

Caractéristiques clés :

  • Pour la déstructuration de paramètres imbriqués, utilisez toujours une interface ou un type.
  • Définissez les valeurs par défaut des champs dans la signature de la fonction.
  • Pour les propriétés optionnelles (age?, address?), pensez toujours aux scénarios où elles peuvent être absentes.

Questions pièges.

Peut-on omettre la description du type de l'objet paramètre — en s'en remettant à l'inférence automatique ?

Non, c'est dangereux. Si vous ne spécifiez pas le type UserOptions, le compilateur ne signalera pas les propriétés obligatoires, les valeurs par défaut ne seront pas prises en compte pour les champs imbriqués, ce qui entraînera des erreurs implicites au moment de l'utilisation.

function example({ x, y }) { ... } // x et y — any

Comment définir une valeur par défaut pour un objet imbriqué, en remplaçant partiellement les propriétés ?

Utilisez le spread. Cependant, le spread ne "fusionne" pas les types si le type address est optionnel. Vous devez faire une vérification ou définir la valeur par défaut explicitement.

function fn({ obj = { foo: 1 } }: { obj?: { foo: number } }) { const address = { foo: 42, ...obj }; }

Quels sont les dangers de la déstructuration avec des champs optionnels sans valeur par défaut ?

Si vous omettez une valeur par défaut pour des propriétés optionnelles, les accès aux propriétés (par exemple, address.city) peuvent provoquer des erreurs à l'exécution. Il est préférable de définir explicitement ? et une valeur par défaut.

function danger({ address }: { address?: { city: string } }) { console.log(address.city); // Erreur, address peut être undefined }

Erreurs typiques et anti-patterns

  • Typage implicite des arguments déstructurés (any)
  • Absence de valeur par défaut pour les propriétés imbriquées/optionnelles
  • Non-utilisation d'interfaces et d'alias de type pour les paramètres structurels

Exemple de la vie réelle

Cas négatif

Dans un ancien code, l'objet de paramètres était déstructuré sans typage explicite. Lors de l'ajout d'un nouveau champ à la fonction, tous les points d'utilisation n'ont pas été automatiquement identifiés, ce qui a cassé les appels en production.

Avantages :

  • Écriture rapide et simple

Inconvénients :

  • Absence de sécurité et de contrôle sur la structure
  • Fragilité lors des modifications

Cas positif

Nous avons introduit des interfaces pour toutes ces fonctions, couvert les scénarios avec des undefined et des valeurs par défaut par des tests, et les suggestions du compilateur ont permis de réaliser facilement des modifications en masse.

Avantages :

  • Haute sécurité des types
  • Simplicité de refactorisation et d'évolutivité

Inconvénients :

  • Un peu plus de texte dans les déclarations de types