Implémenter des interfaces en JavaScript avec Implement.js

Josh J
Josh J

Suivre
Nov 7, 2017 · 5 min de lecture

Dans cet article de blog, je présenterai le concept d’interfaces et comment elles peuvent être utiles même dans les langages dynamiques. Je vais également utiliser l’implémentation de la bibliothèque.js pour apporter le concept à JavaScript et vous montrer comment tirer un utilitaire supplémentaire des interfaces.

Google définit une interface comme  » un point où deux systèmes, des sujets, des organisations, etc. se rencontrer et interagir « ” et cette définition est valable pour les interfaces en programmation. En développement logiciel, une interface est une structure qui applique des propriétés spécifiques à un objet — dans la plupart des langages, cet objet est une classe.

Voici un exemple d’interface en Java:

Dans l’exemple ci-dessus, l’interface Car décrit une classe qui a deux méthodes sans type de retour, qui prennent toutes deux un seul argument entier. Les détails de l’implémentation de chaque fonction sont laissés à la classe, c’est pourquoi les méthodes n’ont pas toutes les deux de corps. Pour s’assurer qu’une classe implémente l’interface Car, nous utilisons le mot-clé implements:

Simple

Les interfaces en JavaScript

Les interfaces ne sont pas une chose en JavaScript, pas vraiment de toute façon. JavaScript est un langage dynamique, où les types sont modifiés si souvent que le développeur ne s’en est peut-être même pas rendu compte, à cause de cela, les gens affirment qu’il n’est pas nécessaire d’ajouter une interface à la norme ECMAScript sur laquelle JavaScript est basé.

Cependant, JavaScript s’est massivement développé en tant que langage backend sous la forme de Node.js, et avec cela viennent des exigences différentes et une foule différente qui peut avoir une opinion différente. Pour ajouter à cela, le langage devient rapidement l’outil frontal; il est arrivé au point où de nombreux développeurs écriront la grande majorité de leur code HTML à l’intérieur.fichiers js sous forme de JSX.

Alors que le langage se développe pour prendre plus de rôles, il est utile de s’assurer que l’une de nos structures de données les plus cruciales est ce que nous attendions qu’elle soit. JavaScript peut avoir le mot clé class, mais en vérité, il ne s’agit que d’une fonction de constructeur désinstallée, et une fois appelée, c’est simplement un objet. Les objets étant omniprésents, il est parfois avantageux de s’assurer qu’ils correspondent à une forme spécifique.

Récemment au travail, j’ai trouvé un cas où un développeur s’attendait à ce qu’une propriété retournée dans le cadre d’une réponse API soit true mais a plutôt obtenu "true", provoquant un bug. Une erreur facile, et qui aurait également pu être évitée si nous avions une interface.

Mais attendez, il y a plus!

Les interfaces, avec quelques modifications mineures, pourraient être utilisées pour remodeler des objets. Imaginez implémenter une interface « stricte », où aucune propriété en dehors de l’interface n’est autorisée, nous pourrions supprimer ou renommer ces propriétés, ou même lancer une erreur si nous les rencontrons.

Nous avons donc maintenant une interface qui nous dira quand il nous manque certaines propriétés, mais aussi quand nous avons des propriétés inattendues, ou si les types de propriétés ne sont pas ce à quoi nous nous attendons. Cela ajoute d’autres possibilités, par exemple la refactorisation d’une réponse d’une API tout en ajoutant cette couche de sécurité supplémentaire au comportement standard de l’interface. Nous pourrions également utiliser des interfaces dans les tests unitaires si nous avons des erreurs de lancement.

Implémenter.js

Implémenter.js est une bibliothèque qui tente d’apporter des interfaces à JavaScript. L’idée est simple: définir une interface, définir les types de ses propriétés et l’utiliser pour s’assurer qu’un objet est ce que vous attendez de lui.

Setup

Installez d’abord le paquet :

npm install implement-js

Ensuite, créez un.js file et import implementInterface, et type:

Notre première interface

Pour créer une interface, appelez simplement Interface et passez une chaîne comme nom de votre interface — ce n’est pas recommandé, mais si vous omettez le nom, un identifiant unique sera généré. Cela renvoie une fonction qui accepte un objet où les propriétés sont toutes des objets type, un deuxième argument peut également être passé avec des options pour afficher des avertissements, lancer des erreurs, supprimer ou renommer des propriétés, s’assurer que seules les propriétés de l’interface sont présentes, ou pour étendre un Interface existant.

Voici une interface qui décrit une voiture:

Il a une propriété seats qui doit être de type number, un tableau de passagers qui contient des objets qui doivent eux-mêmes implémenter l’interface Passenger, et il contient une Passengerbeep propriété, qui devrait être une fonction. Les options error et strict ont été définies sur true, ce qui signifie que des erreurs seront générées lorsqu’une propriété de l’interface est manquante et également lorsqu’une propriété non sur l’interface est trouvée.

Implémentation de notre interface

Maintenant, nous voulons implémenter notre interface, dans un exemple simple, nous allons créer un objet en utilisant un littéral d’objet et voir si nous sommes capables d’implémenter notre interface.

Tout d’abord, nous créons un objet Ford, puis nous tenterons de l’implémenter contre notre interface Car:

Comme nous le voyons à partir de le commentaire ci-dessus, cela génère une erreur. Revenons sur notre interface Car:

Nous pouvons voir que si toutes les propriétés sont présentes, le mode strict est également vrai, ce qui signifie que la propriété supplémentaire fuelType provoque une erreur. De plus, bien que nous ayons une propriété passengers, ce n’est pas un tableau.

Afin d’implémenter correctement l’interface, nous supprimons fuelType et modifions la valeur de passengers pour qu’il s’agisse d’un tableau contenant des objets qui implémentent l’interface Passenger:

 » Mais JavaScript n’est pas un langage orienté objet ! »

Il est vrai que même si les interfaces sont généralement associées à des langages orientés objet, et que JavaScript est un langage multi-paradigme qui utilise l’héritage prototypique, les interfaces peuvent toujours être très utiles.

Par exemple, en utilisant implement-js, nous pouvons facilement refactoriser une réponse API tout en nous assurant qu’elle n’a pas dévié de ce à quoi nous nous attendons. Voici un exemple utilisé en conjonction avec redux-thunk:

Tout d’abord, nous définissons l’interface TwitterUser, qui étend l’interface User, en tant qu’objet avec twitterId et twitterUsername propriétés. trim est vrai, ce qui signifie que nous supprimerons toutes les propriétés non décrites sur l’interface TwitterUser. Étant donné que notre API renvoie des propriétés dans un format hostile, nous avons renommé les propriétés de twitter_username et twitter_id en versions camelcase d’elles-mêmes.

Ensuite, nous définissons une action asynchrone avec redux-thunk, l’action déclenche un appel d’API, et nous utilisons notre interface TwitterUser pour supprimer les propriétés que nous ne voulons pas et pour nous assurer qu’elle implémente les propriétés que nous attendons, avec les types corrects. Si vous préférez garder vos créateurs d’action purs (er) ou n’utilisez pas redux-thunk, vous voudrez peut-être vérifier l’interface à l’intérieur de twitterService.getUser et renvoyer le résultat.

Remarque: lors de l’extension d’une interface, les options ne sont pas héritées

Les tests unitaires sont également un endroit approprié pour utiliser les interfaces:

En résumé

Nous avons vu comment les interfaces peuvent être utiles en JavaScript: même s’il s’agit d’un langage très dynamique, vérifier la forme d’un objet et que ses propriétés sont un type de données spécifique nous donne une couche supplémentaire de sécurité que nous manquerions autrement. En nous appuyant sur le concept d’interfaces et en utilisant implement-js, nous avons également pu acquérir une utilité supplémentaire en plus de la sécurité supplémentaire.

Posted on

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.