TypeScript for Beginners, Part 3 Interfaces

Nous avons commencé cette série par un didacticiel d’introduction qui vous a présenté différentes fonctionnalités de TypeScript. Il vous a également appris comment installer TypeScript et a suggéré quelques environnements de développement intégré (IDE) que vous pouvez utiliser pour écrire et compiler votre propre code TypeScript.. 

Dans le deuxième didacticiel, nous avons abordé différents types de données disponibles dans TypeScript et expliqué comment leur utilisation peut vous aider à éviter beaucoup d’erreurs. Assigner un type de données comme un chaîne à une variable particulière indique à TypeScript que vous souhaitez uniquement lui affecter une chaîne. En s’appuyant sur ces informations, TypeScript peut vous les signaler ultérieurement lorsque vous essayez d’effectuer une opération qui n’est pas censée être effectuée sur des chaînes..

Dans ce tutoriel, vous apprendrez les interfaces dans TypeScript. Avec les interfaces, vous pouvez aller plus loin et définir la structure ou le type d'objets plus complexes dans votre code. Tout comme les types de variables simples, ces objets devront également suivre un ensemble de règles créées par vous. Cela peut vous aider à écrire du code avec plus de confiance et moins de risque d'erreur..

Créer notre première interface

Supposons que votre code contienne un objet lac et que vous l'utilisiez pour stocker des informations sur certains des plus grands lacs du monde. Cet objet lac aura des propriétés telles que le nom du lac, sa zone, sa longueur, sa profondeur et les pays dans lesquels ce lac existe.

Les noms des lacs seront stockés sous forme de chaîne. La longueur de ces lacs sera exprimée en kilomètres et les superficies en kilomètres carrés, mais ces deux propriétés seront stockées sous forme numérique. Les profondeurs des lacs seront en mètres, et cela pourrait aussi être un flotteur. 

Comme tous ces lacs sont très grands, leurs rives ne se limitent généralement pas à un seul pays. Nous utiliserons un ensemble de chaînes pour stocker les noms de tous les pays situés sur le littoral d'un lac donné. Un booléen peut être utilisé pour spécifier si le lac est en eau salée ou en eau douce. L'extrait de code suivant crée une interface pour notre objet Lake.

interface Lakes nom: chaîne, zone: nombre, longueur: nombre, profondeur: nombre, is Freshwater: booléen, pays: chaîne []

le des lacs interface contient le type de chaque propriété que nous allons utiliser lors de la création de nos objets lac. Si vous essayez maintenant d'affecter différents types de valeurs à l'une de ces propriétés, vous obtiendrez une erreur. Voici un exemple qui stocke des informations sur notre premier lac.

let firstLake: Lakes = nom: 'Mer Caspienne', longueur: 1199, profondeur: 1025, superficie: 371000, isFreshwater: false, pays: ['Kazakhstan', 'Russie', 'Turkménistan', 'Azerbaïdjan', 'Iran ']

Comme vous pouvez le constater, l'ordre dans lequel vous affectez une valeur à ces propriétés n'a pas d'importance. Cependant, vous ne pouvez pas omettre de valeur. Vous devrez attribuer une valeur à chaque propriété afin d'éviter les erreurs lors de la compilation du code. 

De cette façon, TypeScript garantit que vous n’avez oublié aucune des valeurs requises par erreur. Voici un exemple où nous avons oublié d’attribuer la valeur du profondeur propriété pour un lac.

let secondLake: Lakes = nom: 'Supérieur', longueur: 616, superficie: 82100, is Freshwater: vrai, pays: ['Canada', 'États-Unis']

La capture d'écran ci-dessous montre le message d'erreur dans Visual Studio Code après que nous ayons oublié de spécifier le profondeur. Comme vous pouvez le constater, l’erreur indique clairement que nous manquons le profondeur propriété pour notre objet lac.

Rendre les propriétés de l'interface facultatives

Parfois, vous pouvez avoir besoin d’une propriété uniquement pour certains objets spécifiques. Par exemple, supposons que vous souhaitiez ajouter une propriété pour spécifier les mois pendant lesquels un lac est gelé. Si vous ajoutez la propriété directement à l'interface, comme nous l'avons fait jusqu'à présent, vous obtiendrez une erreur pour les autres lacs qui ne gèlent pas et n'ont donc pas congelé propriété. De même, si vous ajoutez cette propriété à des lacs gelés mais non dans la déclaration d'interface, vous obtiendrez toujours une erreur..

Dans ce cas, vous pouvez ajouter un point d'interrogation (?) après le nom d'une propriété pour la définir comme facultative dans la déclaration d'interface. De cette façon, vous ne recevrez pas d'erreur pour les propriétés manquantes ou inconnues. L’exemple suivant devrait indiquer clairement.

interface Lakes (Nom: chaîne, zone: nombre, longueur: nombre, profondeur: nombre, is Freshwater: booléen, pays: chaîne [], figé?: chaîne [] let secondLake: Lakes = nom: 'Supérieur', profondeur: 406.3, longueur: 616, superficie: 82100, eau douce: vrai, pays: ['Canada', 'États-Unis'] laissez tiersLake: Lacs = nom: 'Baikal', profondeur: 1637, longueur: 636, superficie: 31500 , isFreshwater: true, pays: ['Russie'], figé: ['janvier', 'février', 'mars', 'avril', 'mai']

Utilisation de signatures d'index

Les propriétés facultatives sont utiles lorsque bon nombre de vos objets vont les utiliser. Cependant, que se passe-t-il si chaque lac possède également son propre ensemble de propriétés, telles que des activités économiques, la population de différentes espèces de flore et de faune florissantes dans ce lac ou les agglomérations qui l’entourent? Ajouter autant de propriétés différentes dans la déclaration de l'interface elle-même et les rendre facultatives n'est pas idéal.

En tant que solution, TypeScript vous permet d'ajouter des propriétés supplémentaires à des objets spécifiques à l'aide de signatures d'index. L'ajout d'une signature d'index à la déclaration d'interface vous permet de spécifier autant de propriétés que vous le souhaitez pour les différents objets que vous créez. Vous devez apporter les modifications suivantes à l'interface. 

Dans cet exemple, j'ai utilisé une signature d'index pour ajouter des informations sur différents établissements autour des lacs. Puisque chaque lac aura ses propres colonies, l'utilisation de propriétés optionnelles n'aurait pas été une bonne idée..

interface Lakes [nom: chaîne, zone: nombre, longueur: nombre, profondeur: nombre, isFreshwater: booléen, pays: chaîne [], figé?: chaîne [], [extraProp: chaîne]: tout laissez quatrièmeLake: Lac =  nom: 'Tanganyika', profondeur: 1470, longueur: 676, superficie: 32600, eau douce: vrai, pays: ['Burundi', 'Tanzanie', 'Zambie', 'Congo'], kigoma: 'Tanzanie', kalemie: 'Congo', bujumbura: 'Burundi'

Autre exemple, supposons que vous créez un jeu avec différents types d’ennemis. Tous ces ennemis auront des propriétés communes comme leur taille et leur santé. Ces propriétés peuvent être incluses directement dans la déclaration d'interface. Si chaque catégorie de ces ennemis possède un ensemble unique d’armes, ces armes peuvent être incluses à l’aide d’une signature indexée..

Propriétés en lecture seule

Lorsque vous travaillez avec différents objets, vous devrez peut-être utiliser des propriétés qui ne doivent être modifiées que lors de la création initiale de l'objet. Vous pouvez marquer ces propriétés comme lecture seulement dans la déclaration d'interface. Ceci est similaire à l'utilisation de la const mot-clé, mais const est censé être utilisé avec des variables, tandis que lecture seulement est destiné aux propriétés.

TypeScript vous permet également de créer des tableaux en lecture seule à l’aide de ReadonlyArray. La création d'un tableau en lecture seule entraînera la suppression de toutes les méthodes en mutation. Ceci est fait pour vous assurer que vous ne pourrez pas modifier la valeur d'éléments individuels ultérieurement. Voici un exemple d'utilisation de propriétés en lecture seule et de tableaux dans les déclarations d'interface.

interface Enemy readonly taille: nombre, santé: nombre, plage: nombre, lecture seulement dommages: nombre let tank: Enemy = taille: 50, santé: 100, plage: 60, dégâts: 12 // C'est un tank correct. santé = 95; // Erreur car 'damage' est en lecture seule. tank.damage = 10;

Fonctions et interfaces

Vous pouvez également utiliser des interfaces pour décrire un type de fonction. Cela nécessite que vous donniez à la fonction une signature d'appel avec sa liste de paramètres et son type de retour. Vous devez également fournir un nom et un type pour chacun des paramètres. Voici un exemple:

interface EnemyHit (nom: Enemy, damageDone: number): numéro;  let tankHit: EnemyHit = function (nom du réservoir: Ennemi, dommageDone: nombre) nom du réservoir.health - = dommageFone; return tankName.health; 

Dans le code ci-dessus, nous avons déclaré une interface de fonction et l'avons utilisée pour définir une fonction qui soustrait des dommages subis par un tank à son état de santé. Comme vous pouvez le constater, il n'est pas nécessaire d'utiliser le même nom pour les paramètres dans la déclaration d'interface et la définition pour que le code fonctionne..

Dernières pensées

Ce didacticiel vous a présenté les interfaces et leur utilisation pour vous assurer de rédiger un code plus robuste. Vous devriez maintenant pouvoir créer vos propres interfaces avec des propriétés facultatives et en lecture seule.. 

Vous avez également appris à utiliser les signatures d'index pour ajouter diverses propriétés à un objet qui ne sont pas incluses dans la déclaration d'interface. Ce didacticiel était destiné à vous familiariser avec les interfaces dans TypeScript. Vous pouvez en lire plus à ce sujet dans la documentation officielle..

Dans le prochain tutoriel, vous en apprendrez plus sur les classes dans TypeScript. Si vous avez des questions relatives aux interfaces, faites-le moi savoir dans les commentaires..